From patchwork Tue Jan 19 12:31:09 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Niklas_S=C3=B6derlund?= X-Patchwork-Id: 10886 X-Patchwork-Delegate: niklas.soderlund@ragnatech.se 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 36ADCC0F1C for ; Tue, 19 Jan 2021 12:31:19 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id E075B68148; Tue, 19 Jan 2021 13:31:18 +0100 (CET) Received: from bin-mail-out-06.binero.net (bin-mail-out-06.binero.net [195.74.38.229]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id E4CC86813F for ; Tue, 19 Jan 2021 13:31:16 +0100 (CET) X-Halon-ID: 390fd88b-5a52-11eb-a542-005056917a89 Authorized-sender: niklas.soderlund@fsdn.se Received: from bismarck.berto.se (p4fca2458.dip0.t-ipconnect.de [79.202.36.88]) by bin-vsp-out-01.atm.binero.net (Halon) with ESMTPA id 390fd88b-5a52-11eb-a542-005056917a89; Tue, 19 Jan 2021 13:31:16 +0100 (CET) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Tue, 19 Jan 2021 13:31:09 +0100 Message-Id: <20210119123110.2976971-2-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210119123110.2976971-1-niklas.soderlund@ragnatech.se> References: <20210119123110.2976971-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 1/2] cam: event_loop: Stop queuing calls when the event loop are exiting 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" Terminating the event loop with EventLoop::exit() does not grantee that it will terminate. If the event loops 'call later' queue can be kept non-empty by continuously queuing new calls using EventLoop::callLater() either from a different thread or from callbacks in the loop itself EventLoop::dispatchCalls() will never complete and the loop will run forever. Solve this by not accepting new callbacks once the event loop is exiting. Reported-by: Sebastian Fricke Fixes: f49e93338b6309a6 ("cam: event_loop: Add deferred calls support") Signed-off-by: Niklas Söderlund --- src/cam/event_loop.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cam/event_loop.cpp b/src/cam/event_loop.cpp index 94c5d1d362455f33..34a55da30c537ac7 100644 --- a/src/cam/event_loop.cpp +++ b/src/cam/event_loop.cpp @@ -62,7 +62,7 @@ void EventLoop::interrupt() void EventLoop::callLater(const std::function &func) { - { + if (!exit_.load(std::memory_order_acquire)) { std::unique_lock locker(lock_); calls_.push_back(func); } From patchwork Tue Jan 19 12:31:10 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Niklas_S=C3=B6derlund?= X-Patchwork-Id: 10887 X-Patchwork-Delegate: niklas.soderlund@ragnatech.se 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 DE728C0F1C for ; Tue, 19 Jan 2021 12:31:19 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 06B3B6814C; Tue, 19 Jan 2021 13:31:19 +0100 (CET) Received: from vsp-unauthed02.binero.net (vsp-unauthed02.binero.net [195.74.38.227]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 7170F60314 for ; Tue, 19 Jan 2021 13:31:17 +0100 (CET) X-Halon-ID: 39a097cf-5a52-11eb-a542-005056917a89 Authorized-sender: niklas.soderlund@fsdn.se Received: from bismarck.berto.se (p4fca2458.dip0.t-ipconnect.de [79.202.36.88]) by bin-vsp-out-01.atm.binero.net (Halon) with ESMTPA id 39a097cf-5a52-11eb-a542-005056917a89; Tue, 19 Jan 2021 13:31:16 +0100 (CET) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Tue, 19 Jan 2021 13:31:10 +0100 Message-Id: <20210119123110.2976971-3-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210119123110.2976971-1-niklas.soderlund@ragnatech.se> References: <20210119123110.2976971-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 2/2] cam: Fix capturing an precis number of requests 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" When moving request processing from the camera manager thread to the main thread a subtle race condition where added when running with the --capture=N option. Before the change the check of how many request had been queued was ran in the camera manager thread and thus could not race with the producer thread. After the change if requests are completed faster then they are consumed (the consumer writes them to disk for example) the check may be delayed and more then the expected number of request may be asked to processed. Sebastian Fricke Fixes: 02eae70e15bdbb24 ("cam: Move request processing to main thread") Signed-off-by: Niklas Söderlund --- src/cam/capture.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/cam/capture.cpp b/src/cam/capture.cpp index 113ea49d50046e5b..ef1601c716bfa137 100644 --- a/src/cam/capture.cpp +++ b/src/cam/capture.cpp @@ -157,6 +157,12 @@ void Capture::requestComplete(Request *request) if (request->status() == Request::RequestCancelled) return; + captureCount_++; + if (captureLimit_ && captureCount_ > captureLimit_) { + loop_->exit(0); + return; + } + /* * Defer processing of the completed request to the event loop, to avoid * blocking the camera manager thread. @@ -206,12 +212,6 @@ void Capture::processRequest(Request *request) std::cout << info.str() << std::endl; - captureCount_++; - if (captureLimit_ && captureCount_ >= captureLimit_) { - loop_->exit(0); - return; - } - request->reuse(Request::ReuseBuffers); camera_->queueRequest(request); }