RE: [boost] Re: recursive mutex and condition

James Ahlborn <james.ahlborn@med.ge.com> wrote:
Ben Hutchings <ben.hutchings <at> businesswebsoftware.com> writes:
I don't believe so. If waiting for a condition releases the mutex only once, this can result in deadlock, and if it releases the mutex completely the protected data can be seen while its invariant is broken. There seems to be no right way to use recursive mutexes with condition variables.
umm, using a condition fundamentally implies releasing a mutex and then reacquiring it. regardless of the mutex type, one needs to make sure that the invariants are valid when the mutex is released.
Yes, I understand all this. <snip>
I think you should avoid using recursive mutexes. Read <http://groups.google.com/groups?selm=3434E6BA.ABD%40zko.dec.com>.
well, i've programmed significantly in both java and c++ and i think the poster of that comment is mistaken on many fronts. besides the obvious bias against java and the seemingly minimal knowledge of how "synchronized" works in java,
"Minimal knowledge"? Does that mean you think he's wrong in fact, or that his opinion about its usefulness is mistaken?
i think the fundamental argument of a recursive mutex being the "lazy man's mutex" is wrong. In any moderately complex system, trying to avoid using recursive mutexes adds complexity to the overall design and eventually breaks the modularity of the system.
As I understand it, your reason for using a recursive mutex would be that there are functions that require a weaker invariant and may safely be called from a function that holds the mutex and has broken the normal invariant, but may also be called without the mutex being held. (If a function requires the normal invariant then you need to re-establish that before calling it, and having done so you could safely unlock the mutex, removing the need for it to be recursive.) This means that responsibility for re-establishing the normal invariant for a recursive mutex is divided up between several functions. So how can the single function that waits on the condition re-establish the invariant? Wouldn't that require a gross breach of the modularity you want? <snip>
to return to boost specifically, the implementation of recursive_mutex and condition seem to imply their combined use. I see no documentation which says "hey, you should only use condition with a normal mutex", nor any compiler error when i try to do so. i see no "fundamental" reason why a recursive mutex and a condition should not work together (they are quite happy in java).
I do.
yet, they don't work, and I'm wondering if that is intended or a bug in boost.
It looks like a documentation bug to me.

Ben Hutchings <ben.hutchings <at> businesswebsoftware.com> writes:
yet, they don't work, and I'm wondering if that is intended or a bug in boost.
It looks like a documentation bug to me.
Actually, if you see my other recent post, i tracked down the bug in boost. If you look at the implementation of recursive_mutex, it was clearly intended to work with conditions. The mptask and winthreads versions are correct, but there was a minor bug in the pthread version for which i posted a patch. -james

It looks like a documentation bug to me.
in mho, if a bug exists than it is in design. if a recursive mutex should not be used in a condition the condition should not accept it. this is either a design flaw (allowing the condition to accept recursive mutexes) or a implementation flaw (the condition should only unlock the recursive mutex once instead all the way).

"Vukasin Toroman" <vtoroman@astaro.de> wrote in message news:418892BF.7070701@astaro.de...
It looks like a documentation bug to me.
in mho, if a bug exists than it is in design. if a recursive mutex should not be used in a condition the condition should not accept it.
They are intended to be used together.
this is either a design flaw (allowing the condition to accept recursive mutexes) or a implementation flaw (the condition should only unlock the recursive mutex once instead all the way).
I don't think that makes sense, though: recursive_mutex m; condition c; bool b; void f() { lock lock1(m); //... lock lock2(m); //Recursive lock while (!b) c.wait(lock2); //*** } At the point marked "***", the thread calling c.wait() (call it thread #1) is waiting for another thread (thread #2) to wake it up. Presumably thread #2 will want to read or modify the resource protected by m before doing so (otherwise there's not much point in thread #1 waiting for it), but it won't be able to because the mutex is still locked by thread #1. If it tries to obtain the mutex, deadlock results. Mike

Michael Glassford wrote: [...]
lock lock1(m);
//...
lock lock2(m); //Recursive lock
while (!b) c.wait(lock2); //***
[...]
deadlock results.
POSIX threads philosophy is that (quoting DRB) "when a thread does call another routine while holding a mutex, (with the exception of unlock and wait!) the called code MUST assume that the mutex is locked because one or more program invariants are broken. That's WHY you lock mutexes, and when the invarient is no longer broken, you should UNLOCK them. ... If you "spin out" the recursive lock to free it, you are breaking the calling code by exposing the supposedly protected (broken) invariants to other threads, unprepared to handle this." So deadlock isn't that bad. ;-) See also: http://lists.boost.org/MailArchives/boost/msg67187.php regards, alexander.

... Using A Condition Variable - A Complete Example ...
3. The mutex itself MUST be a recursive mutex. In order to see why, look at the code of the 'handle_requests_loop' function. You will notice that it first locks the mutex, and afterwards calls the 'get_request' function, which locks
If we used a non-recursive mutex, we'd get locked indefinitely in
Incidentally I found the following, which I think applies to the case: http://users.actcom.co.il/~choo/lupg/tutorials/multi-thread/multi-thread.htm... the mutex again. the mutex locking
operation of the 'get_request' function.
Don't get me wrong, altough I understand the reasoning of the various posters, the use of recursive mutex does not seem to be considered wrong in general. Roland
participants (6)
-
Alexander Terekhov
-
Ben Hutchings
-
James Ahlborn
-
Michael Glassford
-
Roland Schwarz
-
Vukasin Toroman