Switch QSemaphore::tryAcquire to using QDeadlineTimer

A deadline timer is more correct for timeouts.

Also starts the timer before trying to acquire the mutex for more
precise timeouts.

Task-number: QTBUG-58745
Change-Id: I230266a3a5d7b7af33981efed4e6882e5727a41c
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
Allan Sandfeld Jensen 2017-04-12 17:34:41 +02:00
parent ab2c1f9509
commit eaee1209f0

View File

@ -42,7 +42,7 @@
#ifndef QT_NO_THREAD
#include "qmutex.h"
#include "qwaitcondition.h"
#include "qelapsedtimer.h"
#include "qdeadlinetimer.h"
#include "qdatetime.h"
QT_BEGIN_NAMESPACE
@ -214,20 +214,19 @@ bool QSemaphore::tryAcquire(int n)
bool QSemaphore::tryAcquire(int n, int timeout)
{
Q_ASSERT_X(n >= 0, "QSemaphore::tryAcquire", "parameter 'n' must be non-negative");
if (timeout < 0)
return tryAcquire(n);
QDeadlineTimer timer(timeout);
QMutexLocker locker(&d->mutex);
if (timeout < 0) {
while (n > d->avail)
d->cond.wait(locker.mutex());
} else {
QElapsedTimer timer;
timer.start();
while (n > d->avail) {
const qint64 elapsed = timer.elapsed();
if (timeout - elapsed <= 0
|| !d->cond.wait(locker.mutex(), timeout - elapsed))
return false;
}
qint64 remainingTime = timer.remainingTime();
while (n > d->avail && remainingTime > 0) {
if (!d->cond.wait(locker.mutex(), remainingTime))
return false;
remainingTime = timer.remainingTime();
}
if (n > d->avail)
return false;
d->avail -= n;
return true;