Mark, (and group) I may not have explained myself clearly in my original message. Your example ThreadedQueue::bMessageAvaliable() const actually demonstrates _exactly_ why I feel that condition::wait should be const. Your method modifies something internally (a boost::mutex; I have no argument whatsoever with the view that locking a mutex changes its state). Then it does some other things that don't affect its const-ness. Then it undoes the modifications it originally made. (By unlocking the mutex) A caller of this function should not care that these things go on internally. In this sense, it is logically const. I would also add that the caller of the function does not care that the precise behavior (say, when it returns, or in other examples, the exact value that it does) of the function can depend on the actions of other threads; this is the point that I had expected resistance on.) Similarly, the condition::wait will modify a mutex (unlocking it, and yes, through a non-const Lock object). It will do some other stuff. Bookkeeping or whatever, maybe even blocking itself. No matter what it does internally, by the time it returns control to its caller, all of this has been undone. The thread is not blocked. It is not in a waiting queue. The mutex that we pointed it at has been locked again. From the caller's perspective, the only things different after the call are: 1. Time has passed. 2. Some other threads have done some things that they might not have done otherwise. What they do is their own business. I don't see how that can affect this function's const-ness. (Am I missing something _here_?) My conclusion is that condition::wait is logically const. I will certainly admit that const-ness may be in the eye of the beholder. I expect that the physically const vs. logically const is a problem with some people. However, there do seem to be other examples of functions that are const (in their signatures) in the same spirit that my intuition tells me condition::wait is. Does this elucidate my position? Weston Markham Mark Sizer wrote: The condition wait() requires a lock, which requires a mutex. The mutex state is toggled from acquired to free to acquired whilst the wait() is waiting. It's the same problem that having a lock creates on a method such as this one: ThreadedQueue::bMessageAvailable() const { { boost::mutex::scoped_lock( _mutexQueue ) return !_queue.empty(); } } The only way to make that work is to declare the _mutexQueue as "mutable". In the case above, I agree with you: In terms of logical "const-ness", these methods are (or can be) const. In terms of physical "const-ness", they are not. Solve the problem with "mutable". However, the condition case is a bit more subtle. ThreadedQueue::messageNext() const { { boost::mutex::scoped_lock lockQueue( _mutexQueue ); if ( _queueOut.empty() ) { // (the lock is released before blocking, // then re-locked before continuing) _conditionMessageReady.wait( lockQueue ); } // get a message } } Is that really const? if the _mutexQueue and _conditionMessageReady are made "mutable" we can MAKE the method const (as shown), but is it? I'd say there is a EXPLICIT state change in the object: Into the waiting state. This is a change, therefore non-const. In the bMessageAvailable() case, there is no explicit state change, you're returning the existing state of the object. There is an implicit state change required to safely do so, which we've decided to hide. The only way this can block forever is bad coding - deadlock. When using a condition.wait(), you are making 2 big state changes: Both the object and the thread involved go from a "running" state into a "blocked" state, perhaps forever if nothing notifies (which is reasonable if the event never occurrs, not a coding deadlock error). That doesn't seem "const" to me. - Mark