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>
This commit is contained in:
Mårten Nordheim 2023-05-16 17:57:12 +02:00
parent 443068dbba
commit 288326eaf8

View File

@ -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;
while (true) {
const DWORD timeout = deadline.isForever()
? INFINITE
: DWORD(std::min(deadline.remainingTime(), qint64(INFINITE - 1)));
case WAIT_OBJECT_0:
ret = true;
break;
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)
@ -123,6 +129,13 @@ 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;
@ -130,7 +143,7 @@ bool QWaitCondition::wait(QMutex *mutex, unsigned long time)
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