Search code examples
c++boost-thread

boost::condition_variable.timed_wait return immediately


I'm working on a little threading library and have run into a problem. boost::condition_variable.wait() works perfectly, however boost::condition_variable.timed_wait() returns immediately, it doesn't time out.

The documentation says it should only return once the timeout has passed or it's been notified. It's a three second wait before notification and I've tried both 10 second and 100 second timouts, so it should return after 3 seconds.

EDIT:

boost::condition_variable waitCondition;
boost::mutex mMutex;

Message MessageClient::waitAsync(Message msg, bool waitForReply) {
   unique_lock<boost::mutex> lock(msg->mMutex);
   if(mSendTimeout.sec == 0)
       msg->waitCondition.wait(lock);
   else {
       timeout = msg->waitCondition.timed_wait(lock,  mSendTimeout);
       if(!timeout)
           return 0;

       if(waitForReply) {
          Message reply = receiveMessage();
          return reply;
       }
       else
          return 0;
}

This is called after a sendMessage. The receiver get the message, sends the reply and then calls

waitCondition.notify_all();

Solution

  • Condition variable waits can occasionally result in spurious wakeups. As such, you must use them in a loop:

    while (someCondition)
      msg->waitCondition.wait(lock);
    

    With timed_wait it's slightly more complex as you must recalculate your timeout to deal with however long it did, in fact, wait. Boost offers a variant with a predicate that, given an absolute timeout, will do the loop for you:

    msg->waitCondition.timed_wait(lock, absoluteTimeout, boost::lambda::var(someFlag));
    

    If you're still having problems, check that mSendTimeout is not negative or very small, and consider the use of an absolute timeout.