
My intuition is to make it work. Meaning that the wait() will unlock lock_count() times, to a full unlock state, and then lock it back again the same amout of times. Why shouldn't it work?
Ok, I'll try to explain, altough I am afraid I am not too good in this. You are true, in believing that it can be made working. But you are about to create extremely dangerous code by this.
Once you place this semantics into work _every_ subroutine call from within a locked scope attains wait semantics, i.e the state of your locked memory might have changed. This wouldn't be expected by most programmers.
E.g.
... { scoped_lock l(m); // do something to the locked data foo(); // call a member function which _might_ wait // do something else to the locked data // ouch, the locking was removed in between, data has // unexpectedly changed. I did not expect this, did you? }
I can't understand why this example shows why a condition variable with recursive mutex is dangerous. How this example would be any different if the mutex is non-recursive? Calling foo() which might wait, *always* have the potential of releasing the mutex, so a recursive mutex doesn't change anything here. And this is, actually, a good thing, that it doesn't change anything. This way the behaviour is expected, and all is dandy.
Ok, this is no good, but why then allow recursive mutex anyways?
I find it harder to come up with a convincing example, but basically I think to forbid it entirely simply is too strict. It is possible to write correct, yet safe programs with recursive_mutex. I'll try:
<snip exmaple why a condition variable with recursive mutex can be useful> I disagree that the runtime correctness issue in this example is relevant to the condition variable stuff. This example had some logic about what can or can't be the answer, and tried to manipulate the condition variable to validate this. I find this very confusing. If I wanted to say that an asnwer smaller than 42 is a runtime error, then I'd just write if (answer < 42) throw ...; which is much simpler and understandable. IMHO, Condition variable are meant for completely different purposes than checking runtime correctness of application business logic.
Of course, better programming style would have choosen a different grouping of the functions, so the recursive_mutex could have been avoided entirely. But you also have things like reinterpret_cast<> which usually are beeing avoided whenever possible. Still it is there because there are times when it is useful, you simply have to put a lot more thought into it when using it.
Ok, then. If it's considered ok, then allow it, as I can't find any good reason to say that a recursive mutex is ok, but a condition variable with such a mutex is not ok. Of course, anything I say is completely my humble opinion, and may very well turn out to be complete nonsense. Yuval