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