Condition variables should have have a single order with respect to notify()
and unlock_sleep()
(an imaginary function call used within wait()
where the mutex is unlocked and the thread sleeps as one atomic sequence of operations) operations. To achieve this with arbitrary lockables std::condition_variable_any
implementations typically use another mutex internally (to ensure atomicity and to sleep on)
If the internal unlock_sleep()
and notify()
(notify_one()
or notify_all()
) operations are not atomic with respect to each other you risk a thread unlocking the mutex, another thread signaling and then the original thread going to sleep and never waking up.
I was reading the libstdc++ and libc++ implementations of std::condition_variable_any and noticed this code in the libc++ implementation
{lock_guard<mutex> __lx(*__mut_);}
__cv_.notify_one();
the internal mutex is locked and then immediately unlocked before the signal operation. Doesn't this risk the problem I described above?