From patchwork Sat Jan 30 00:19:14 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: 11069 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 C6F55BD808 for ; Sat, 30 Jan 2021 00:19:40 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 595E6683CA; Sat, 30 Jan 2021 01:19:39 +0100 (CET) Received: from vsp-unauthed02.binero.net (vsp-unauthed02.binero.net [195.74.38.227]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 3E503683BE for ; Sat, 30 Jan 2021 01:19:38 +0100 (CET) X-Halon-ID: d5c197ae-6290-11eb-b73f-0050569116f7 Authorized-sender: niklas.soderlund@fsdn.se Received: from bismarck.berto.se (p4fca2458.dip0.t-ipconnect.de [79.202.36.88]) by bin-vsp-out-03.atm.binero.net (Halon) with ESMTPA id d5c197ae-6290-11eb-b73f-0050569116f7; Sat, 30 Jan 2021 01:19:37 +0100 (CET) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Sat, 30 Jan 2021 01:19:14 +0100 Message-Id: <20210130001915.489703-2-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210130001915.489703-1-niklas.soderlund@ragnatech.se> References: <20210130001915.489703-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 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 only executing the already queued calls each invocation of dispatchCalls() and only enter the idle loop if dispatchCalls() had no calls to dispatch. Reported-by: Sebastian Fricke Fixes: f49e93338b6309a6 ("cam: event_loop: Add deferred calls support") Signed-off-by: Niklas Söderlund --- src/cam/event_loop.cpp | 21 +++++++++------------ src/cam/event_loop.h | 2 +- 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/src/cam/event_loop.cpp b/src/cam/event_loop.cpp index 94c5d1d362455f33..f0b1ecbb6244c40a 100644 --- a/src/cam/event_loop.cpp +++ b/src/cam/event_loop.cpp @@ -41,8 +41,8 @@ int EventLoop::exec() exit_.store(false, std::memory_order_release); while (!exit_.load(std::memory_order_acquire)) { - dispatchCalls(); - event_base_loop(event_, EVLOOP_NO_EXIT_ON_EMPTY); + if (!dispatchCalls()) + event_base_loop(event_, EVLOOP_NO_EXIT_ON_EMPTY); } return exitCode_; @@ -70,17 +70,14 @@ void EventLoop::callLater(const std::function &func) interrupt(); } -void EventLoop::dispatchCalls() +bool EventLoop::dispatchCalls() { - std::unique_lock locker(lock_); + lock_.lock(); + std::list> calls = std::move(calls_); + lock_.unlock(); - for (auto iter = calls_.begin(); iter != calls_.end(); ) { - std::function call = std::move(*iter); - - iter = calls_.erase(iter); - - locker.unlock(); + for (std::function call : calls) call(); - locker.lock(); - } + + return !calls.empty(); } diff --git a/src/cam/event_loop.h b/src/cam/event_loop.h index 408073c50594d09d..b2535f7bdd96742a 100644 --- a/src/cam/event_loop.h +++ b/src/cam/event_loop.h @@ -38,7 +38,7 @@ private: std::mutex lock_; void interrupt(); - void dispatchCalls(); + bool dispatchCalls(); }; #endif /* __CAM_EVENT_LOOP_H__ */