From patchwork Thu Jan 30 11:51:41 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= X-Patchwork-Id: 22678 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 0AE91BD808 for ; Thu, 30 Jan 2025 11:51:50 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id C070F68586; Thu, 30 Jan 2025 12:51:49 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=protonmail.com header.i=@protonmail.com header.b="iTVx9enu"; dkim-atps=neutral Received: from mail-10631.protonmail.ch (mail-10631.protonmail.ch [79.135.106.31]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 99E8C68585 for ; Thu, 30 Jan 2025 12:51:47 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=protonmail.com; s=protonmail3; t=1738237907; x=1738497107; bh=WA9XW3ePOxUFoUm4S12Lvq92T+nfxRnepdlU4S8fWwg=; h=Date:To:From:Subject:Message-ID:In-Reply-To:References: Feedback-ID:From:To:Cc:Date:Subject:Reply-To:Feedback-ID: Message-ID:BIMI-Selector:List-Unsubscribe:List-Unsubscribe-Post; b=iTVx9enuH0bykoK+WF5Klr1yYR0D9PtOZDMgaip3jn5U+bPA+MN7j9IPmVcv/4W/r Fa0cFGSiqJksgIKputaQm4TLtetbuju0k7DPPG20ymMhFJ+XrbVmfIY6VVYWIRASPj WqtIRNkT1JR3+CKPSz8ORMQdZYFLlDiQqCGrGx+0CILMO1xqCPtQhTrUU1Fj3KwLeg vETwHlYcmbUYU4J6drs0gGrdbJiKHYr2cEI7yxUWvXRGBJKHmz6/+lD8e6acmviemq Tkz4CaLCr8g/g3dSkhP8JbiPjD0yJs4YtZV5ub5kugUaOdCUbPgYcSwTZ6O+WS1Yho oHRjkxi6q4mYA== Date: Thu, 30 Jan 2025 11:51:41 +0000 To: libcamera-devel@lists.libcamera.org From: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= Subject: [RFC PATCH v3 19/21] apps: lc-compliance: Run request completion handler in "main" thread Message-ID: <20250130115001.1129305-20-pobrn@protonmail.com> In-Reply-To: <20250130115001.1129305-1-pobrn@protonmail.com> References: <20250130115001.1129305-1-pobrn@protonmail.com> Feedback-ID: 20568564:user:proton X-Pm-Message-ID: 8d23c9458e26aa7527bad0cb73628c6c8a0e7d6f MIME-Version: 1.0 X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Currently, `Capture::requestCompleted()` runs in the `CameraManager`'s thread. This makes it a bit more complicated to use googletest and report errors in those callbacks since lc-compliance sets up googletest to throw exceptions on fatal errors / test skip, but those exceptions are only caught on the "main" thread, the one running the test suite. To minimize the burden of dealing with synchronization in tests, execute `Capture::requestCompleted()` in the event loop's thread by utilizing `EventLoop::callLater()`. Signed-off-by: Barnabás Pőcze Reviewed-by: Jacopo Mondi --- src/apps/lc-compliance/helpers/capture.cpp | 24 +++++++++++++--------- src/apps/lc-compliance/helpers/capture.h | 2 +- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/src/apps/lc-compliance/helpers/capture.cpp b/src/apps/lc-compliance/helpers/capture.cpp index 4a8627662..5032470d9 100644 --- a/src/apps/lc-compliance/helpers/capture.cpp +++ b/src/apps/lc-compliance/helpers/capture.cpp @@ -127,17 +127,13 @@ void Capture::prepareRequests() } } -int Capture::queueRequest(libcamera::Request *request) +void Capture::queueRequest(libcamera::Request *request) { if (queueLimit_ && queueCount_ >= *queueLimit_) - return 0; - - int ret = camera_->queueRequest(request); - if (ret < 0) - return ret; + return; + ASSERT_EQ(camera_->queueRequest(request), 0); queueCount_ += 1; - return 0; } void Capture::requestComplete(Request *request) @@ -152,8 +148,7 @@ void Capture::requestComplete(Request *request) << "Request didn't complete successfully"; request->reuse(Request::ReuseBuffers); - if (queueRequest(request)) - loop_->exit(-EINVAL); + queueRequest(request); } void Capture::start() @@ -172,7 +167,14 @@ void Capture::start() ASSERT_TRUE(allocator_.allocated()); - camera_->requestCompleted.connect(this, &Capture::requestComplete); + camera_->requestCompleted.connect(this, [this](libcamera::Request *request) { + /* Runs in the CameraManager thread. */ + + loop_->callLater([this, request] { + /* Run handler in the context of the event loop. */ + requestComplete(request); + }, reinterpret_cast(this)); + }); ASSERT_EQ(camera_->start(), 0) << "Failed to start camera"; } @@ -188,6 +190,8 @@ void Capture::stop() requests_.clear(); + loop_->cancelLater(reinterpret_cast(this)); + for (const auto &cfg : *config_) { int ret = allocator_.free(cfg.stream()); EXPECT_EQ(ret, 0) << "Failed to free buffers associated with stream"; diff --git a/src/apps/lc-compliance/helpers/capture.h b/src/apps/lc-compliance/helpers/capture.h index 48a8dadcb..dacce1fe2 100644 --- a/src/apps/lc-compliance/helpers/capture.h +++ b/src/apps/lc-compliance/helpers/capture.h @@ -30,7 +30,7 @@ private: void stop(); void prepareRequests(); - int queueRequest(libcamera::Request *request); + void queueRequest(libcamera::Request *request); void requestComplete(libcamera::Request *request); std::shared_ptr camera_;