[RFC PATCH v1] libcamera: thread: Fix event dispatcher creation
Barnabás Pőcze
pobrn at protonmail.com
Tue Jan 28 14:03:14 CET 2025
Use an appropriate compare-and-exchange atomic instruction
to set the event dispatcher pointer. This ensures that there
is only ever a single event dispatcher associated with a
given thread.
Consider e.g. the following series of events:
1. thread 0 :: if (!data_->dispatcher_.load(std::memory_order_relaxed))
// reads nullptr and proceeds into the `if`'s block
2. thread 1 :: if (!data_->dispatcher_.load(std::memory_order_relaxed))
// reads nullptr and proceeds into the `if`'s block
3. thread 0 :: data_->dispatcher_.store(new EventDispatcherPoll(), std::memory_order_release);
// creates dispatcher and sets pointer
4. thread 1 :: data_->dispatcher_.store(new EventDispatcherPoll(), std::memory_order_release);
// creates dispatcher and sets pointer
At the end, one of the event dispatchers is leaked, and
furthermore the `eventDispatcher()` calls might return
different values in the calling threads.
Signed-off-by: Barnabás Pőcze <pobrn at protonmail.com>
---
src/libcamera/base/thread.cpp | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/src/libcamera/base/thread.cpp b/src/libcamera/base/thread.cpp
index de60567f6..93ec7b5a0 100644
--- a/src/libcamera/base/thread.cpp
+++ b/src/libcamera/base/thread.cpp
@@ -518,11 +518,16 @@ pid_t Thread::currentId()
*/
EventDispatcher *Thread::eventDispatcher()
{
- if (!data_->dispatcher_.load(std::memory_order_relaxed))
- data_->dispatcher_.store(new EventDispatcherPoll(),
- std::memory_order_release);
+ if (EventDispatcher *dispatcher = data_->dispatcher_.load(std::memory_order_acquire))
+ return dispatcher;
- return data_->dispatcher_.load(std::memory_order_relaxed);
+ auto dispatcher = std::make_unique<EventDispatcherPoll>();
+ EventDispatcher *expected = nullptr;
+
+ if (data_->dispatcher_.compare_exchange_strong(expected, dispatcher.get(), std::memory_order_acq_rel))
+ return dispatcher.release();
+
+ return expected;
}
/**
--
2.48.1
More information about the libcamera-devel
mailing list