$include_dir="/home/hyper-archives/boost-users/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-users] condition_variable
From: Alessandro Bellina (abellina_at_[hidden])
Date: 2009-12-09 08:50:06
Hello,
I am using boost condition_variables to block while waiting for an
asynchronous response. I am seeing an error that happens at random whenever
I am releasing the lock just before calling notify_one. The error goes away
if I keep the lock and release after notify_one.
Here is the code:
class BlockingRequest{
        public:
        // predicate class
        class ResponseStatus
        {
        public:
            ResponseStatus( bool& received ) : m_received( received )
            {
            }
            bool operator()() const
            {
                return m_received;
            }
        private:
            bool& m_received;
        };
          //blocking request
std::string Request( const std::string& request )
{
     boost::mutex::scoped_lock lock( mutex );
     //perform asynchronous request through network or something else, pass
RequestHandler as a handler
     boost::posix_time::milliseconds timeoutDuration( 10000 ); //wait for 10
seconds
     if( !condition.timed_wait( lock, timeoutDuration, ResponseStatus(
received ) ) )
     {
           throw std::exception( "Request timed out" );
     }
     return receivedMessage;
}
//some other thread calls this function
void RequestHandler( const std::string& message, void* caller )
{
     BlockingRequest* myRequest = reinterpret_cast< BlockingRequest* >(
caller );
     boost::mutex::scoped_lock lock( myRequest->mutex );
     myRequest->receivedMessage = message;
     myRequest->received = true;
     /*
        if this next line in bold is commented out, code works fine...
contrary to Boost documentation.
http://www.boost.org/doc/libs/1_41_0/doc/html/thread/synchronization.html#thread.synchronization.condvar_ref
     */
     *lock.unlock();*
     myRequest->condition.notify_one();
}
};