Skip to content

Commit e13f49a

Browse files
committed
fix(gateway): synchronize with worker before notify in ResourceChangeNotifier::shutdown
Classical lost-wakeup race between shutdown() and worker_loop(): 1. worker locks queue_mutex_ 2. worker checks predicate (flag=false, queue empty) -> false 3. shutdown() CAS flag -> true (NOT holding queue_mutex_) 4. shutdown() notify_one() - worker NOT yet enqueued on CV 5. worker enters wait(lock): atomic unlock+enqueue+sleep 6. worker sleeps forever; main blocks in worker_thread_.join() Even though shutdown_flag_ uses seq_cst atomics, the worker's predicate check and entry into wait() are not atomic with respect to the flag modification. The notify can arrive before the worker is enqueued. Fix: briefly acquire queue_mutex_ between setting the flag and notifying. This guarantees the worker is either still outside its critical section (will observe the new flag on the next lock) or already enqueued on the CV (notify_one will wake it). Manifested as a TSan-specific hang in DoubleShutdownIsSafe (worker spawn + immediate shutdown hits the race window).
1 parent 7068ad0 commit e13f49a

1 file changed

Lines changed: 7 additions & 0 deletions

File tree

src/ros2_medkit_gateway/src/resource_change_notifier.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,13 @@ void ResourceChangeNotifier::shutdown() {
105105
});
106106
}
107107

108+
// Synchronize with worker_loop()'s predicate check. Without this, the flag
109+
// store above can land between the worker's predicate evaluation and its
110+
// wait() call, losing the subsequent notify_one(). Acquiring queue_mutex_
111+
// here guarantees the worker is either still outside the critical section
112+
// (will observe the new flag) or already enqueued on queue_cv_ (notify will
113+
// wake it).
114+
{ std::lock_guard<std::mutex> sync(queue_mutex_); }
108115
queue_cv_.notify_one();
109116
if (worker_thread_.joinable()) {
110117
worker_thread_.join();

0 commit comments

Comments
 (0)