
"vicente.botet" <vicente.botet@wanadoo.fr> writes:
----- Original Message ----- From: "Anthony Williams" <anthony@justsoftwaresolutions.co.uk> To: <threads-devel@lists.boost.org> Sent: Monday, April 14, 2008 5:34 PM Subject: Re: [Threads-devel] [boost] Expected behaviour of condition variable wait when unique_lock is not locked
Quoting "vicente.botet" <vicente.botet@wanadoo.fr>:
which is the expected behaviour of condition variable wait when unique_lock is not locked
Undefined behaviour: a precondition has not been met.
IMO this is not satisfactory. At least an exception should be thrown. And the C++0x recomendation states this.
"void wait(unique_lock<mutex>& lock); Precondition: lock is locked by the current thread, and either: No other thread is waiting on this condition_variable object, or The lock arguments supplied by all concurrently waiting threads (via wait or timed_wait) return the same value for lock.mutex(). Effects: Atomically calls lock.unlock() and blocks on *this. When unblocked, calls lock.lock() (possibly blocking on the lock) and returns. The function will unblock when this thread is signaled by a call to this->notify_one(), a call to this->notify_all(), or spuriously. If the function exits via an exception, lock.lock() will still be called prior to exiting the function scope. Postconditions: lock is locked by the current thread. Throws: system_error when the effects or postconditions cannot be achieved. "
Then you're reading it differently to how it was written. The precondition is "lock is locked by the current thread". If the precondition is violated, all bets are off.
I'm wondering why the condition_variable wait operation do not requires a strict lock (the one introduced by Andrei Alexandrescu in his article about external locking "Multithreading and the C++ Type System") instead of a unique lock or whatever.
The wait must unlock the mutex and then lock it again. By using unique_lock (which supports that), this possibility is explicit. condition_variable_any will support any lock type that has unlock() and lock() operations. Boost 1.34 and prior used hidden traits types to unlock and relock the mutex, which I don't think is desirable. The Boost 1.35 "strict lock" is boost::lock_guard. Anthony -- Anthony Williams | Just Software Solutions Ltd Custom Software Development | http://www.justsoftwaresolutions.co.uk Registered in England, Company Number 5478976. Registered Office: 15 Carrallack Mews, St Just, Cornwall, TR19 7UL