Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QWaitCondition: how to avoid lost wakeup?

QWaitCondition: how to avoid lost wakeup?

Scheduled Pinned Locked Moved Solved General and Desktop
2 Posts 1 Posters 1.3k Views 2 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • B Offline
    B Offline
    Bart_Vandewoestyne
    wrote on last edited by
    #1

    Quite recently, we have detected a QWaitCondition in our code that suffers from
    the lost wakeup problem. For more information on this problem,
    please refer to http://www.modernescpp.com/index.php/condition-variables that
    describes it for C++11's std::condition_variable (I believe the
    description there is also valid for condition variables of type QWaitCondition).

    Basically, what we do is the following: we first send a message to a server,
    and then wait for a reply using something like the following:

    bool SomeController::mfWaitForAnswer(int timeoutInMilliSeconds)
    {
        bool responseReceivedWithinTimeout = true;
    
        mvResponseReceivedMutex.lock();
    
        if (!mvResponseReceived)
        {
            responseReceivedWithinTimeout = mvWait.wait(&mvResponseReceivedMutex, 
                                                        timeoutInMilliSeconds);
        }
    
        mvResponseReceivedMutex.unlock();
    
        return responseReceivedWithinTimeout;
    }
    

    where mvWait is the problematic QWaitCondition. Elsewhere, we have the wakeup
    code that gets executed when a message from the server arrives:

    void SomeController::mpMessageReceived(const QString& message)
    {
        mvResponseReceivedMutex.lock();
    
        mvMessage = message;
        mvResponseReceived = true;
        mvWait.wakeAll();
    
        mvResponseReceivedMutex.unlock();
    }
    

    The problem is that if the server is very fast to reply, then the call to
    mvWait.wakeAll() occurs between the sending of the message to the server and
    the mvWait.wait() call. Thus, the QWaitCondition is not waiting yet and we have
    a lost wakeup.

    Now, on http://www.modernescpp.com/index.php/condition-variables it is
    explained that for std::condition_variable::wait, one can add a Predicate to
    overcome this problem. See also
    http://en.cppreference.com/w/cpp/thread/condition_variable/wait However, I
    don't see such a facility for QWaitCondition.

    I'm quite sure we are not the only ones suffering from the lost wakeup issue
    with a QWaitCondition. Can I get some advice on what is the typical way to
    address this? (Note that we are still using Qt 4.8.7 and time and priorities
    are holding us from upgrading yet...)

    B 1 Reply Last reply
    0
    • B Bart_Vandewoestyne

      Quite recently, we have detected a QWaitCondition in our code that suffers from
      the lost wakeup problem. For more information on this problem,
      please refer to http://www.modernescpp.com/index.php/condition-variables that
      describes it for C++11's std::condition_variable (I believe the
      description there is also valid for condition variables of type QWaitCondition).

      Basically, what we do is the following: we first send a message to a server,
      and then wait for a reply using something like the following:

      bool SomeController::mfWaitForAnswer(int timeoutInMilliSeconds)
      {
          bool responseReceivedWithinTimeout = true;
      
          mvResponseReceivedMutex.lock();
      
          if (!mvResponseReceived)
          {
              responseReceivedWithinTimeout = mvWait.wait(&mvResponseReceivedMutex, 
                                                          timeoutInMilliSeconds);
          }
      
          mvResponseReceivedMutex.unlock();
      
          return responseReceivedWithinTimeout;
      }
      

      where mvWait is the problematic QWaitCondition. Elsewhere, we have the wakeup
      code that gets executed when a message from the server arrives:

      void SomeController::mpMessageReceived(const QString& message)
      {
          mvResponseReceivedMutex.lock();
      
          mvMessage = message;
          mvResponseReceived = true;
          mvWait.wakeAll();
      
          mvResponseReceivedMutex.unlock();
      }
      

      The problem is that if the server is very fast to reply, then the call to
      mvWait.wakeAll() occurs between the sending of the message to the server and
      the mvWait.wait() call. Thus, the QWaitCondition is not waiting yet and we have
      a lost wakeup.

      Now, on http://www.modernescpp.com/index.php/condition-variables it is
      explained that for std::condition_variable::wait, one can add a Predicate to
      overcome this problem. See also
      http://en.cppreference.com/w/cpp/thread/condition_variable/wait However, I
      don't see such a facility for QWaitCondition.

      I'm quite sure we are not the only ones suffering from the lost wakeup issue
      with a QWaitCondition. Can I get some advice on what is the typical way to
      address this? (Note that we are still using Qt 4.8.7 and time and priorities
      are holding us from upgrading yet...)

      B Offline
      B Offline
      Bart_Vandewoestyne
      wrote on last edited by
      #2

      Problem solved. My original diagnose was incorrect: we did not suffer from the Lost Wakeup problem. The real problem was that mpMessageReceived was never called. The reason why it never got called was that we had a non-working signal-slot connection. And the reason for that non-working signal-slot connection was that there was no event loop running (where we thought there was).

      1 Reply Last reply
      3

      • Login

      • Login or register to search.
      • First post
        Last post
      0
      • Categories
      • Recent
      • Tags
      • Popular
      • Users
      • Groups
      • Search
      • Get Qt Extensions
      • Unsolved