$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
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.