[rerepost][threads] recursive shared_mutex
I promise this is the last time I repost this; if I got no response I'll go
and try somewhere else :-/ thanks for your patience.
As the docs do not explicitly say otherwise, I guess I must assume that
boost::shared_mutex is not recursive with respect to unique ownership,
that is, the following behavior ensues:
shared_mutex mutex;
lock_guard
joaquin tid dot es:
I promise this is the last time I repost this; if I got no response I'll go and try somewhere else :-/ thanks for your patience.
As the docs do not explicitly say otherwise, I guess I must assume that boost::shared_mutex is not recursive with respect to unique ownership, that is, the following behavior ensues:
shared_mutex mutex; lock_guard
lock1(mutex); lock_guard lock2(mutex); // DEADLOCK Is this so? In case boost::shared_mutex is indeed non-recursive, I've read the following assertion on Hinnant's paper N2406 (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2406.html ):
"A recursive shared mutex could be built upon shared_mutex if desired, but this is not proposed."
Does anyone has a reference on how to construct a recursive shared_mutex from a non-recursive one?
1. Recursive mutexes are evil. 2. The basic technique is http://www.decadentplace.org.uk/pipermail/cpp-threads/2006-August/001082.htm... (except that the store_release to count_ is not necessary, it's under a lock, count_ = 1 is sufficient) but, as I point out, it requires an atomic thread ID type. In the shared_mutex case, you'll want to use the same trick inside lock_shared to prevent the sequence exclusive_lock, shared_lock from deadlocking. shared_lock followed by exclusive_lock from the same thread is not worth supporting "properly"; luckily, it doesn't occur under the typical use patterns of recursive locking since const members don't call non-const ones.
2. The basic technique is
http://www.decadentplace.org.uk/pipermail/cpp-threads/2006-August/001082.htm...
(except that the store_release to count_ is not necessary, it's under a lock, count_ = 1 is sufficient)
but, as I point out, it requires an atomic thread ID type.
One could probably use boost::detail::spinlock_pool for that. Peter, thanks for providing this :-) BTW, do you plan to release spinlocks as a regular Boost library? Regards, Filip
Filip Konvicka:
2. The basic technique is
http://www.decadentplace.org.uk/pipermail/cpp-threads/2006-August/001082.htm... (except that the store_release to count_ is not necessary, it's under a lock, count_ = 1 is sufficient)
but, as I point out, it requires an atomic thread ID type.
One could probably use boost::detail::spinlock_pool for that.
It would probably be too slow. On platforms where the native "thread ID" is not an atomic type, one might use (in "C++0x pseudocode") unsigned get_thread_id() { static thread_local unsigned t_tid; static std::atomic<unsigned> s_tid; if( t_tid == 0 ) { t_tid = ++s_tid; } return t_tid; }
Peter, thanks for providing this :-) BTW, do you plan to release spinlocks as a regular Boost library?
I'm not ready to do that at the moment.
participants (3)
-
Filip Konvička
-
joaquin@tid.es
-
Peter Dimov