
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