Again, duh on me. Thank you. I don't want to use the 'while' paradigm, because I want to be able to free all the blocked threads on shutdown so they all gracefully terminate (destructors called, etc...). Getting a default constructed message back is OK as long as it's rare. I've refactored to this (it seems to work, but I'm posting it anyway): MSG mqueue::get() { MSG msgResult; { boost::mutex::scoped_lock lockQueue( _mutexQueue ); if ( _queueOut.empty() ) { _conditionMessageReady.wait( lockQueue ); } if ( !_queueOut.empty() ) { msgResult = _queueOut.front(); _queueOut.pop(); } else { // this happens after a flush() call (on shutdown) // (and the occasional race condition) } } return msgResult; } ( and changed post back to .notify_one() ) Thanks again, - Mark Christopher Currie wrote:
Mark,
The problem is that your "get" waits on the condition before it checks if the condition has already been met. So if you call "get" after the producer has already "post"ed, you'll sit on the condition forever. The canonical form of waiting on a condition looks like this:
MSG mqueue::get(); { MSG msgResult; { boost::mutex::scoped_lock lockQueue( _mutexQueue ); while ( _queueOut.empty() )
_conditionMessageReady.wait( lockQueue );
msgResult = _queueOut.front();
_queueOut.pop(); } return msgResult; }
Now if you call get and there's something in the queue, there's no need to wait on the condition.
P.S. The lockQueue is locked when the condition is done waiting, right?
Yes, the lock is automatically released when entering wait, and acquired before exiting it.
Hope this helps!
Christopher
Info: http://www.boost.org Wiki: http://www.crystalclearsoftware.com/cgi-bin/boost_wiki/wiki.pl Unsubscribe: mailto:boost-users-unsubscribe@yahoogroups.com
Your use of Yahoo! Groups is subject to http://docs.yahoo.com/info/terms/