|
Boost : |
From: Howard Hinnant (hinnant_at_[hidden])
Date: 2004-07-09 18:33:39
On Jul 9, 2004, at 6:05 PM, Peter Dimov wrote:
> Howard Hinnant wrote:
>> On Jul 9, 2004, at 4:11 PM, Peter Dimov wrote:
>>
>>>> rw_mutex m;
>>>>
>>>> void invitation_for_deadlock()
>>>> {
>>>> read_lock r(m);
>>>> // ok to read
>>>> upgradable_read_lock ur(m);
>>>> r.unlock();
>>>> write_lock w(ur);
>>>> // ok to write
>>>> }
>>>>
>>>> And the next thing we'll know is that the entire NE US is falling
>>>> into a blackout. ;-)
>>>>
>>>> It took me awhile to spot the deadlock in the above code. Does
>>>> anyone else see the above code as scary? (scary as in looks ok but
>>>> isn't). Or is the deadlock obvious to everyone else (and thus not
>>>> scary)?
>>>
>>> Not scary, IMO, even if not obvious, because it always deadlocks, as
>>> soon as you attempt the "idiom". You can't miss it.
>>
>> I'm not following "always deadlocks". If only one thread enters, at
>> what point does it deadlock (assuming no other thread playing with m)?
>> Experimentally running through this on my prototype implementation
>> with
>> a single thread isn't deadlocking. But perhaps my prototype is buggy?
>
> I wouldn't bet on that. Can I change my opinion to "scary"? ;-)
<chuckle> Only fools and idiots *never* change their mind! :-)
So that's two votes for scary. I'm still undecided if it is "too
scary". I.e. will documentation make upgradable_read_lock sufficiently
safe? I'm hoping so, because there seems to be a vocal need for that
functionality, and I don't see a good alternative at the moment.
A good rule of thumb for using rw_mutex seems to be that you should
never hold more than one lock on it in the same thread. Now that I
write that though, I'm wondering if holding a recursive read_lock might
be safe enough.... haven't looked into yet. But holding a read_lock
and an upgradable_read_lock in the same thread is definitely
ill-advised, even if only for an instant.
At great extra expense one could put a runtime check into rw_mutex for
one thread owning both a read_mutex and an upgradable_read_mutex. It
would require storing a vector<thread_id> for every thread sharing read
ownership. That would probably make the rw_mutex so expensive as to be
useless though.
-Howard
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk