
Jens Finkhäuser <jens@unwesen.de> writes:
Hi!
On Mon, Nov 03, 2008 at 08:00:08AM +0000, Anthony Williams wrote:
Jens FinkhÀuser <jens@unwesen.de> writes:
Hi!
I've come across something that puzzles me. I've got code that, condensed to relevant parts, looks like this:
recursive_mutex m; lock_guard<recursive_mutex> l1(m); lock_guard<recursive_mutex> l2(m, adopt_lock_t());
That is an error. adopt_lock_t means that l2 takes ownership of the already-locked mutex (i.e. doesn't lock it again), but it doesn't force l1 to relinquish ownership, so both l2 and l1 think they own the one and only lock. When l2 is destroyed it will unlock the mutex, and then when l1 is destroyed it will unlock the mutex AGAIN, which is undefined behaviour because it doesn't own the mutex at this point.
<snip/>
Thanks for your reply. I understand your argument, and what the code *does*, just not the reasoning: how then is adopt_lock_t *supposed* to work? It's not as if you can tell lock_guard to relinquish ownership of a mutex.
No, you can't. If you need to do that, use unique_lock and the release() member function.
If there is no need to adopt a mutex because there's only one lock in the code, adopt_lock_t is superfluous. If there are two locks involved, you'll always run into an issue where one lock gets to unlock the mutex first - and the other one fails.
Yes. Don't do that. adopt_lock_t is for where you've locked the mutex *directly* using mutex.lock(), or where you've acquired a locked mutex from a unique_lock using unique_lock::release(). It works quite well with the boost::lock free functions: boost::mutex m1,m2; boost::lock(m1,m2); // lock both mutexes boost::lock_guard<boost::mutex> l1(m1,boost::adopt_lock); boost::lock_guard<boost::mutex> l2(m2,boost::adopt_lock); In this case, you can also use unique_lock with the defer_lock constructor: boost::unique_lock<boost::mutex> l1(m1,boost::defer_lock); boost::unique_lock<boost::mutex> l2(m2,boost::defer_lock); boost::lock(l1,l2); // lock both mutexes Anthony -- Anthony Williams Author of C++ Concurrency in Action | http://www.manning.com/williams Custom Software Development | http://www.justsoftwaresolutions.co.uk Just Software Solutions Ltd, Registered in England, Company Number 5478976. Registered Office: 15 Carrallack Mews, St Just, Cornwall, TR19 7UL, UK