3 ms·
> The wait condition is associated with a mutex, which is locked by the user when calling wake() and that is also passed locked to wait(). The implementation is
by ridiculous_fish 6y ago
> The wait condition is associated with a mutex, which is locked by the user when calling wake() and that is also passed locked to wait(). The implementation is supposed to unlock and wait atomically.
In POSIX it is not necessary to lock the mutex before calling wake(). In fact it is better unlock the mutex first, and then call wake(), because otherwise the just-woken thread will contend with the waker. Given that fact, the race really is unavoidable.
- gpderetta 6y agoA few years ago I strongly defended this very point on here HN. As far as I knew, you only need to signal while owning the lock if you want to rely on the stronger guarantees of realtime scheduling. Since then I stumbled upon another scenario were you need to hold the lock for correctness: a producer calls pthread_cond_signal which wakes up a waiter that then destroys the condition variable. This would get flagged by tsan and often cause segfaults especially when the memory is freed. It was not obvious from the docs that this is not allowed, but as apparently pthread_cond_signal can still inspect the condition variable states after waking a waiter. My use case was fairly simple (I was implementing an event count), so I reimplemented it on top of a raw futex and made sure that signal would return straight away, but signaling while holding the mutex and only destroying the condvar after releasing the mutex would have also fixed it.