diff options
author | Mårten Nordheim <marten.nordheim@qt.io> | 2023-05-16 17:57:12 +0200 |
---|---|---|
committer | Mårten Nordheim <marten.nordheim@qt.io> | 2023-06-01 17:10:10 +0000 |
commit | 288326eaf8819f9c3bf978bd11af8ea0ce3ca4f0 (patch) | |
tree | 7cb6e5fab3f61f5abaa857047da9879cfafbba0d /src | |
parent | 443068dbba39696923cf852d8eccbbfb5f8571a7 (diff) |
QWaitCondition/win: Enable actually waiting longer than u32::max
This is done, in part, by swapping the dependency between the wait() overloads.
Furthermore, since QDeadlineTimer is 64-bit and the Win32 API is 32-bit
we have to wait more than once to actually wait until the deadline
is reached.
The unsigned int overload has no documented concept of waiting
'forever'. Though, internally we turn u32::max into 'forever'.
Change-Id: I47d719c0c29bcd6fa0c0043d168a456f2c05774e
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/corelib/thread/qwaitcondition_win.cpp | 52 |
1 files changed, 31 insertions, 21 deletions
diff --git a/src/corelib/thread/qwaitcondition_win.cpp b/src/corelib/thread/qwaitcondition_win.cpp index c176241f47..ba53309e1b 100644 --- a/src/corelib/thread/qwaitcondition_win.cpp +++ b/src/corelib/thread/qwaitcondition_win.cpp @@ -43,7 +43,7 @@ public: EventQueue freeQueue; QWaitConditionEvent *pre(); - bool wait(QWaitConditionEvent *wce, unsigned long time); + bool wait(QWaitConditionEvent *wce, QDeadlineTimer deadline); void post(QWaitConditionEvent *wce, bool ret); }; @@ -68,19 +68,25 @@ QWaitConditionEvent *QWaitConditionPrivate::pre() return wce; } -bool QWaitConditionPrivate::wait(QWaitConditionEvent *wce, unsigned long time) +bool QWaitConditionPrivate::wait(QWaitConditionEvent *wce, QDeadlineTimer deadline) { // wait for the event - bool ret = false; - switch (WaitForSingleObjectEx(wce->event, time, FALSE)) { - default: - break; - - case WAIT_OBJECT_0: - ret = true; - break; + while (true) { + const DWORD timeout = deadline.isForever() + ? INFINITE + : DWORD(std::min(deadline.remainingTime(), qint64(INFINITE - 1))); + + switch (WaitForSingleObjectEx(wce->event, timeout, FALSE)) { + case WAIT_OBJECT_0: + return true; + case WAIT_TIMEOUT: + if (deadline.hasExpired()) + return false; + break; + default: + return false; + } } - return ret; } void QWaitConditionPrivate::post(QWaitConditionEvent *wce, bool ret) @@ -124,13 +130,20 @@ QWaitCondition::~QWaitCondition() bool QWaitCondition::wait(QMutex *mutex, unsigned long time) { + if (time == std::numeric_limits<unsigned long>::max()) + return wait(mutex, QDeadlineTimer(QDeadlineTimer::Forever)); + return wait(mutex, QDeadlineTimer(time)); +} + +bool QWaitCondition::wait(QMutex *mutex, QDeadlineTimer deadline) +{ if (!mutex) return false; QWaitConditionEvent *wce = d->pre(); mutex->unlock(); - bool returnValue = d->wait(wce, time); + bool returnValue = d->wait(wce, deadline); mutex->lock(); d->post(wce, returnValue); @@ -138,12 +151,14 @@ bool QWaitCondition::wait(QMutex *mutex, unsigned long time) return returnValue; } -bool QWaitCondition::wait(QMutex *mutex, QDeadlineTimer deadline) +bool QWaitCondition::wait(QReadWriteLock *readWriteLock, unsigned long time) { - return wait(mutex, deadline.remainingTime()); + if (time == std::numeric_limits<unsigned long>::max()) + return wait(readWriteLock, QDeadlineTimer(QDeadlineTimer::Forever)); + return wait(readWriteLock, QDeadlineTimer(time)); } -bool QWaitCondition::wait(QReadWriteLock *readWriteLock, unsigned long time) +bool QWaitCondition::wait(QReadWriteLock *readWriteLock, QDeadlineTimer deadline) { using namespace QReadWriteLockStates; @@ -160,7 +175,7 @@ bool QWaitCondition::wait(QReadWriteLock *readWriteLock, unsigned long time) QWaitConditionEvent *wce = d->pre(); readWriteLock->unlock(); - bool returnValue = d->wait(wce, time); + bool returnValue = d->wait(wce, deadline); if (previousState == LockedForWrite) readWriteLock->lockForWrite(); @@ -171,11 +186,6 @@ bool QWaitCondition::wait(QReadWriteLock *readWriteLock, unsigned long time) return returnValue; } -bool QWaitCondition::wait(QReadWriteLock *readWriteLock, QDeadlineTimer deadline) -{ - return wait(readWriteLock, deadline.remainingTime()); -} - void QWaitCondition::wakeOne() { // wake up the first waiting thread in the queue |