[libcamera-devel] [PATCH 1/2] cam: event_loop: Stop queuing calls when the event loop are exiting
Laurent Pinchart
laurent.pinchart at ideasonboard.com
Tue Jan 19 13:43:17 CET 2021
Hi Niklas,
Thank you for the patch.
On Tue, Jan 19, 2021 at 01:31:09PM +0100, Niklas Söderlund wrote:
> 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 <sebastian.fricke at posteo.net>
> Fixes: f49e93338b6309a6 ("cam: event_loop: Add deferred calls support")
> Signed-off-by: Niklas Söderlund <niklas.soderlund at ragnatech.se>
> ---
> 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<void()> &func)
> {
> - {
> + if (!exit_.load(std::memory_order_acquire)) {
> std::unique_lock<std::mutex> locker(lock_);
> calls_.push_back(func);
> }
That's a bit of a layering violation. Would it make sense to fix this
differently, by ensuring that EventLoop::dispatchCalls() will only
handle deferred calls that are on the list when the function is called ?
This would also ensure that callLater(), when called from the same
thread, will guarantee that pending events get processed before the
delayed call is processed.
I mean something along those lines (only compile-tested).
diff --git a/src/cam/event_loop.cpp b/src/cam/event_loop.cpp
index 94c5d1d36245..320ade525a3f 100644
--- a/src/cam/event_loop.cpp
+++ b/src/cam/event_loop.cpp
@@ -74,7 +74,7 @@ void EventLoop::dispatchCalls()
{
std::unique_lock<std::mutex> locker(lock_);
- for (auto iter = calls_.begin(); iter != calls_.end(); ) {
+ for (auto iter = calls_.begin(), end = calls_.end(); iter != end; ) {
std::function<void()> call = std::move(*iter);
iter = calls_.erase(iter);
--
Regards,
Laurent Pinchart
More information about the libcamera-devel
mailing list