event: prevent potential deadlock
In the `obtain_lock<true>()` path there is a race in which another
thread can run after the `run_condition.signal()` call before the
mutex lock call is executed. This other thread could run a significant
amount of code, including coming around to be back in the `run_one`
path.
To prevent this behavior, add a stage to the lock so that there is an
ordering such that the signalling thread is ensured to get the primary
lock before the signalled thread.
Signed-off-by: Patrick Williams <patrick@stwcx.xyz>
Change-Id: Ia464a95ed55246a67ed87601275a6e1fa8b16ba3
diff --git a/src/event.cpp b/src/event.cpp
index 209bac6..a16f25a 100644
--- a/src/event.cpp
+++ b/src/event.cpp
@@ -176,6 +176,8 @@
template <bool Signal>
std::unique_lock<std::recursive_mutex> event::obtain_lock()
{
+ std::unique_lock stage{this->obtain_lock_stage};
+
std::unique_lock<std::recursive_mutex> l{this->lock, std::defer_lock_t()};
if constexpr (Signal)
{