
I realized that the previous code snippet may be hard to follow, since it was taken out of the middle of a member function. So, here if the member function, in its entirety. Basically, consumer_wait_() is an internal method of a message queue, and would be called from within any get/pop function (i.e., any time a consumer asks for a piece of data off the message queue). When consumer_wait_() returns, the lock is still held, and there is at least one message in the queue. If, for some reason, the consumer can not get the message, an exception is thrown. In this code, an exception can be thrown: 1. the message queue has been shutdown 2. the message queue has been deactivated for GET operations 3. the timeout elapses while waiting for a message to arrive 4. timed_wait() or wait() throws: 1. an internal error in the condition variable/lock will generate a lock_error() exception 2. a then thread_would_block() exception is generated if the mutex type is null_mutex. I guess all code could specialize on null_mutex, but I think what I have added to boost::condition is reasonable for most uses (and the really special ones can always specialize themselves). template <typename Lock> void consumer_wait_( Lock & lock, boost::xtime const * timeout) { struct auto_increment : private boost::noncopyable { auto_increment(unsigned int & t) : t_(t) { ++t_; } ~auto_increment() { --t_; } private: unsigned int & t_; }; #ifndef NDEBUG struct assertions : private boost::noncopyable { assertions( Lock const & lock, size_type const & msgcnt) : lock_(lock) , msgcnt_(msgcnt) { assert(this->lock_.locked()); } ~assertions() { assert(this->lock_.locked()); assert(this->msgcnt_ > 0); } Lock const & lock_; size_type const & msgcnt_; }; assertions assertions(lock, this->msgcnt_); #endif // NDEBUG while (this->is_empty_()) { if (this->is_shutdown_()) { throw shutdown_exception(); } if (!this->is_get_active_()); { throw get_inactive_exception(); } auto_increment num_waiting(this->num_waiting_consumers_); if (timeout) { if (!this->waiting_consumers_cv_.timed_wait(lock, *timeout)) { throw timeout_exception(); } } else { this->waiting_consumers_cv_.wait(lock); } } if (!this->is_get_active_()) { throw get_inactive_exception(); } }