Boost logo

Boost Users :

From: William E. Kempf (wekempf_at_[hidden])
Date: 2003-06-12 09:50:18


db10www said:
> I have created a mutex class which is a model of the mutex concept.
>
> I also have lock classes for this mutex which models the lock
> concept (e.g. called CMyLock).
>
> (The reason for this is to implement a read/write mutex and
> associated read and write locks)
>
> According to the boost documentation I should be able to use this lock
> with the boost::condition but I get a compile time error:-

1) This is an area in the specification that needs much work.

2) I don't believe the docs actually say this, though because of the poor
specification I can understand one coming to this conclusion.

> 'm_mutex' : is not a member of 'CMyLock'
>
> This is due to the condition::wait method defined in condition.hpp
> making a reference to lock.m_mutex
>
> Surely boost::condition only needs a lock object to be an instance of a
> class which is a model of lock.

What a condition actually works with is a Mutex model, not a Lock model.
Passing a Lock is just syntactic sugar that helps remove a frequent
mistake made by programmers... waiting on an unlocked Mutex. So, the
wait() methods have to be able to obtain the associated Mutex from the
Lock, and currently this is done as an implementation detail and not as
part of the public interface. That's one area in which the specification
needs work. However, there's a much more important area as well... and it
relates to your R/W Mutex.

Waiting on a Condition/Mutex is a complex operation with semantics that
are important to the caller. The caller must be able to ensure that all
invariants hold before the call to any Condition wait. Several POSIX
members point out, correctly, that even with a recursive Mutex you can't
always do this, though I'm still struggling with whether or not this
outweighs the benefits of the cases in which you can. In fact, POSIX
basically says that a recursive Mutex will only "behave" on calls to
Condition waits when there's only one level or locks. In Boost.Threads
I've worked around this... but this was a decision that I may be persuaded
to retract at some point.

Next, the call to Condition waits must fully unlock the Mutex before
waiting, or deadlocks will ensue (that's where POSIX leads you, I
believe).

Finally, the call must fully return the Mutex to the state it was in prior
to the call to any wait before it returns.

Like recursive Mutexes, it may well be a bad idea to allow R/W Mutexes to
be used on Condition waits, and for the same basic reason. In addition,
you'd have to fully define what it means to "fully unlock" an R/W Mutex if
it were allowed.

Not all Mutex variants we could imagine can be made to live up to all of
these rules, so not all Mutex types will be allowed with Condition waits.
But I have to figure out how to specify this in a usable manner.

> The lock concept makes no reference to a member variable called
> m_mutex.
>
> Is this a bug of boost::condition or am I doing something wrong.

Neither... it's a problem in the specification which has to be worked out
yet.

-- 
William E. Kempf

Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net