top | item 22002510

(no title)

graetzer | 6 years ago

Its usually a good idea to hold the lock because the other thread(s) might not have called wait() yet.

As a rule of thumb: its usually a bug to not hold the lock before notify(), unless you synchronize it with another condition

discuss

order

usefulcat|6 years ago

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.

ComputerGuru|6 years ago

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.

gpderetta|6 years ago

> 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.

ComputerGuru|6 years ago

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).