In this case I think it should be ok because !this->tasks.empty() is part of the predicate, and will be true after a new item is enqueued (and before notify is called). So if the producer is interrupted between releasing the mutex and calling notify, the consumer would not call wait.
But yeah, in general I agree with the advice.. I'm pretty sure I've made that mistake before.
It depends on if the predicate can (also) be changed without the lock being held, as otherwise the release/acquire ordering semantics are not guaranteed. So long as items are only every enqueued with the lock held, it should be ok.
> its usually a bug to not hold the lock before notify()
All correct non-realtime uses uses of condition variables should work fine with notify called outside of the critical section.
The only case it matters is when using strict realtime scheduling (SCHED_FIFO and SCHED_RR) and it is important that higher priority threads are woken up before lower priority ones.
The exception I guess is when paired with a condition variable, since CV waits are not guaranteed spurious and necessarily must be combined with another condition. The caveat being that the variable being tested upon wake must not be modified without the lock held (presumably to prevent reordering).
usefulcat|6 years ago
But yeah, in general I agree with the advice.. I'm pretty sure I've made that mistake before.
ComputerGuru|6 years ago
gpderetta|6 years ago
All correct non-realtime uses uses of condition variables should work fine with notify called outside of the critical section.
The only case it matters is when using strict realtime scheduling (SCHED_FIFO and SCHED_RR) and it is important that higher priority threads are woken up before lower priority ones.
ComputerGuru|6 years ago