|
Boost : |
From: Alexander Terekhov (terekhov_at_[hidden])
Date: 2004-07-13 09:37:40
Peter Dimov wrote:
[...]
> That's how Boost.Threads behaves, but (AFAICS) it doesn't protect itself
> against a thread switch and lock immediately after freeing the mutex for the
> wait, so it doesn't meet the "correctly" requirement. ;-)
I think it saves the lock count on the stack prior to releasing
internal "real" [non-recursive, in a way, because it's never used
recursively] mutex and restores the count on exit from cv.wait
after acquiring the "real" mutex. In a way, the scheme is really
similar to:
http://groups.google.com/groups?selm=3BA5B950.6E21D198%40web.de
http://groups.google.com/groups?selm=408E48E8.D67F1EA5%40web.de
--- Per-thread flags can be used to turn nonrecursive locks into recursive ones. given: key - tsd flag key lock - mutex (non-recursive lock) count - unsigned init { tsd::init(&key); lock::init(&lock); count = 0; } destroy { lock::destroy(&lock); tsd::destroy(&key); } lock { if (!tsd::get(&key)) { tsd::set(&key, true); lock.acquire(); // assume throw()-nothing count = 1; } else { ++count; } } unlock { if (!--count ) { lock.release(); // throw()-nothing tsd::set(&key, false); } } Note that if you need "posix safety" with respect to unlock/destroy of this lock, "tsd::set(&key, false);" shall be done before "lock.release();" (and of course the underlying nonrecursive lock itself shall be safe with respect to unlock/destroy). --- where you just need to save-on-stack-and-reset/restore the lock count before-cv.enter_wait()/after-cv.exit_wait(). The problem I meant before was something else (don't recall now). regards, alexander.
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk