|
Boost : |
From: Howard Hinnant (hinnant_at_[hidden])
Date: 2004-07-09 19:24:38
On Jul 9, 2004, at 6:54 PM, Glen Knowles wrote:
> From: Howard Hinnant [mailto:hinnant_at_[hidden]]
>> 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
>>>> }
>>>>
>>>> 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?
>
> It only deadlocks under a race, but I'm not sure it's scary. It's
> something
> I'm use to seeing in the presents of r/w locks.
If r/w locks regularly encourage deadlocks, I am not anxious to further
pursue them. I'm not convinced of that however (and hope I won't be).
I'm seeking a system which makes it easy to avoid deadlocks, race
conditions, and leaked locks. Admittedly any system can be abused.
But a good system will naturally reduce accidental abuse, while not
necessarily preventing intentional abuse.
> I don't know where you left off, are you implementing single
> upgradeable or
> multiple upgradeables? If only one upgradeable can exist in the system
> at a
> time then, what would deadlock, will result in a failure to create a
> second
> upgradable lock, IIUC.
Single upgradable.
> You can always manufacture ways to deadlock, I'd still vote for just
> hanging
> a try/timed_promote() on all read locks. Unless perhaps there's
> overhead in
> upgradable_read_lock that isn't required in read_lock?
There's not overhead in the lock, but in the rw_mutex to support both
read/write and upgradable_read. But hanging a try_promote on multiple
upgradable read locks really makes me nervous. Doing so (imho) makes
deadlock significantly more likely (see my post with
lock_both/transfer_lock example).
Fwiw, here's what I'm seeing that is scaring me:
rw_mutex m;
void invitation_for_deadlock()
{
// 1
read_lock r(m);
// ok to read
// 2
upgradable_read_lock ur(m);
// 3
r.unlock();
// 4
write_lock w(ur);
// 5
// ok to write
}
Thread A Thread B
1
2
3
4
1
2
A holds ur.
B holds r.
A waits for B to unlock r so it can unlock ur and lock w.
B waits for A to unlock ur so it can lock ur.
-Howard
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk