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();