From fb187929dd6361dbab10d09ff28d440c0aa0eddf Mon Sep 17 00:00:00 2001 From: Richard Fuchs Date: Thu, 27 Mar 2025 08:09:38 -0400 Subject: [PATCH] MT#62181 fix join race condition In some cases it can happen that ::join() is called from multiple threads at the same time. Checking the ::joinable() flag is not race-free and so is unreliable to make sure that only one other thread attempts to join at any given time. Add a mutex and a state variable to make sure only one thread attempts to join, and make any other threads wait. Change-Id: I02fd236a416b035c98642535f1521be4a3a63fd9 --- core/AmThread.cpp | 15 ++++++++++++--- core/AmThread.h | 6 +++++- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/core/AmThread.cpp b/core/AmThread.cpp index 868d5c1e..49d37bf5 100644 --- a/core/AmThread.cpp +++ b/core/AmThread.cpp @@ -82,9 +82,18 @@ void AmThread::stop() void AmThread::join() { - // only when neither stopped nor joined - if (_td.joinable()) - _td.join(); + // don't attempt to join thread that doesn't exist + if (_state == state::idle) + return; + + // make sure only one other thread joins this one. all others + // are made to wait through the mutex + std::lock_guard _l(_join_mt); + if (!_joined) { + if (_td.joinable()) + _td.join(); + _joined = true; + } } diff --git a/core/AmThread.h b/core/AmThread.h index eb152cb1..39723dea 100644 --- a/core/AmThread.h +++ b/core/AmThread.h @@ -122,6 +122,9 @@ class AmThread std::atomic _state; + std::mutex _join_mt; + bool _joined; + void _start(); protected: @@ -135,7 +138,8 @@ public: unsigned long _pid; AmThread() - : _state(state::idle) + : _state(state::idle), + _joined(false) {} virtual ~AmThread();