Fix "forever" timeout in QtcProcess::waitFor... methods

Change-Id: I57aac503599fa94f530e073164b86b5247702ce5
Reviewed-by: Alessandro Portale <alessandro.portale@qt.io>
This commit is contained in:
Jarek Kobus
2021-11-05 14:55:10 +01:00
parent 12ccd9ec54
commit 0830e50185
2 changed files with 7 additions and 12 deletions

View File

@@ -30,7 +30,6 @@
#include "qtcassert.h" #include "qtcassert.h"
#include <QCoreApplication> #include <QCoreApplication>
#include <QElapsedTimer>
#include <QLocalSocket> #include <QLocalSocket>
#include <QMutexLocker> #include <QMutexLocker>
@@ -542,14 +541,11 @@ bool CallerHandle::isCalledFromLaunchersThread() const
bool LauncherHandle::waitForSignal(int msecs, CallerHandle::SignalType newSignal) bool LauncherHandle::waitForSignal(int msecs, CallerHandle::SignalType newSignal)
{ {
QTC_ASSERT(!isCalledFromLaunchersThread(), return false); QTC_ASSERT(!isCalledFromLaunchersThread(), return false);
QElapsedTimer timer; QDeadlineTimer deadline(msecs);
timer.start();
while (true) { while (true) {
const int remainingMsecs = msecs - timer.elapsed(); if (deadline.hasExpired())
if (remainingMsecs <= 0)
break; break;
const bool timedOut = !doWaitForSignal(qMax(remainingMsecs, 0), newSignal); if (!doWaitForSignal(deadline, newSignal))
if (timedOut)
break; break;
m_awaitingShouldContinue = true; // TODO: make it recursive? m_awaitingShouldContinue = true; // TODO: make it recursive?
const QList<CallerHandle::SignalType> flushedSignals = m_callerHandle->flushFor(newSignal); const QList<CallerHandle::SignalType> flushedSignals = m_callerHandle->flushFor(newSignal);
@@ -563,14 +559,12 @@ bool LauncherHandle::waitForSignal(int msecs, CallerHandle::SignalType newSignal
return true; return true;
if (wasCanceled) if (wasCanceled)
return true; // or false? is false only in case of timeout? return true; // or false? is false only in case of timeout?
if (timer.hasExpired(msecs))
break;
} }
return false; return false;
} }
// Called from caller's thread exclusively. // Called from caller's thread exclusively.
bool LauncherHandle::doWaitForSignal(int msecs, CallerHandle::SignalType newSignal) bool LauncherHandle::doWaitForSignal(QDeadlineTimer deadline, CallerHandle::SignalType newSignal)
{ {
QMutexLocker locker(&m_mutex); QMutexLocker locker(&m_mutex);
QTC_ASSERT(isCalledFromCallersThread(), return false); QTC_ASSERT(isCalledFromCallersThread(), return false);
@@ -585,7 +579,7 @@ bool LauncherHandle::doWaitForSignal(int msecs, CallerHandle::SignalType newSign
return true; return true;
m_waitingFor = newSignal; m_waitingFor = newSignal;
const bool ret = m_waitCondition.wait(&m_mutex, msecs); const bool ret = m_waitCondition.wait(&m_mutex, deadline);
m_waitingFor = CallerHandle::SignalType::NoSignal; m_waitingFor = CallerHandle::SignalType::NoSignal;
return ret; return ret;
} }

View File

@@ -28,6 +28,7 @@
#include "launcherpackets.h" #include "launcherpackets.h"
#include "processutils.h" #include "processutils.h"
#include <QDeadlineTimer>
#include <QHash> #include <QHash>
#include <QMutex> #include <QMutex>
#include <QObject> #include <QObject>
@@ -213,7 +214,7 @@ public:
private: private:
// Called from caller's thread exclusively. // Called from caller's thread exclusively.
bool doWaitForSignal(int msecs, CallerHandle::SignalType newSignal); bool doWaitForSignal(QDeadlineTimer deadline, CallerHandle::SignalType newSignal);
// Called from launcher's thread exclusively. Call me with mutex locked. // Called from launcher's thread exclusively. Call me with mutex locked.
void wakeUpIfWaitingFor(CallerHandle::SignalType newSignal); void wakeUpIfWaitingFor(CallerHandle::SignalType newSignal);