On 9/09/2013 10:34 p.m., Quoth Thomas M:
Now the question: Is there a strong point pro or against releasing controllerLock before the notify_all-signal is sent? E.g. is there preference for the first or second variant as below (see placement of curly brackets!), or even a need for one to ensure correctness?
The normal problem, IIRC, is that notify_all() will only wake up those threads that are actually sleeping on the condition variable already. If you release the lock early, then another thread might enter the locked region, discover that the condition is false, and be about to sleep on the condition variable when the notify is triggered -- it then goes to sleep permanently because it missed the wakeup event.
// simplified code snippet begin - Variant 2 // notify_all is issued when controllerLock has already been released { boost::unique_lockboost::mutex controllerLock(someMutex); Continue = true; } someCondVar.notify_all(); // simplified code snippet end
Given that you are updating the condition within the mutex I believe that this is safe from the above issue. However it still may not be safe due to other factors -- for instance, if the memory containing someCondVar becomes eligible for deletion once the condition is true (which happens more often than you'd think, particularly when the condition includes some sort of termination flag/event) then variant 1 is still safe while variant 2 is not. In terms of efficiency, variant 2 is probably more efficient than variant 1 on a uniprocessor system, but on a multicore system they're probably about the same. (As on uniprocessor there is a chance that the notify could cause an immediate preemption, lockout, and switchback with variant 1, while on a multicore the notifying thread should be able to continue to release the lock.)