QWaitCondition: how to avoid lost wakeup?
-
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'sstd::condition_variable
(I believe the
description there is also valid for condition variables of typeQWaitCondition
).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 problematicQWaitCondition
. 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
themvWait.wait()
call. Thus, theQWaitCondition
is not waiting yet and we have
a lost wakeup.Now, on http://www.modernescpp.com/index.php/condition-variables it is
explained that forstd::condition_variable::wait
, one can add aPredicate
to
overcome this problem. See also
http://en.cppreference.com/w/cpp/thread/condition_variable/wait However, I
don't see such a facility forQWaitCondition
.I'm quite sure we are not the only ones suffering from the lost wakeup issue
with aQWaitCondition
. 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...) -
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).