Boost logo

Boost :

From: Yuval Ronen (ronen_yuval_at_[hidden])
Date: 2005-09-18 13:55:50


>>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


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk