
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.