QAbstractEventDispatcher: port timer uses to the V2 API
Change-Id: I83dda2d36c904517b3c0fffd17b52b71739928dc Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>bb10
parent
afa86c60e6
commit
1ca89b65d8
|
|
@ -165,7 +165,7 @@ void QBasicTimer::start(std::chrono::milliseconds duration, Qt::TimerType timerT
|
|||
}
|
||||
stop();
|
||||
if (obj)
|
||||
id = eventDispatcher->registerTimer(duration.count(), timerType, obj);
|
||||
id = int(eventDispatcher->registerTimer(duration, timerType, obj));
|
||||
}
|
||||
|
||||
/*!
|
||||
|
|
@ -177,7 +177,7 @@ void QBasicTimer::stop()
|
|||
{
|
||||
if (id) {
|
||||
QAbstractEventDispatcher *eventDispatcher = QAbstractEventDispatcher::instance();
|
||||
if (eventDispatcher && !eventDispatcher->unregisterTimer(id)) {
|
||||
if (eventDispatcher && !eventDispatcher->unregisterTimer(Qt::TimerId(id))) {
|
||||
qWarning("QBasicTimer::stop: Failed. Possibly trying to stop from a different thread");
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -330,7 +330,7 @@ QBindable<std::chrono::nanoseconds> QChronoTimer::bindableInterval()
|
|||
std::chrono::nanoseconds QChronoTimer::remainingTime() const
|
||||
{
|
||||
if (isActive())
|
||||
return 1ms * QAbstractEventDispatcher::instance()->remainingTime(qToUnderlying(d_func()->id));
|
||||
return QAbstractEventDispatcher::instance()->remainingTime(d_func()->id);
|
||||
return std::chrono::nanoseconds::min();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1453,7 +1453,7 @@ bool QObject::event(QEvent *e)
|
|||
QThreadData *threadData = d->threadData.loadRelaxed();
|
||||
QAbstractEventDispatcher *eventDispatcher = threadData->eventDispatcher.loadRelaxed();
|
||||
if (eventDispatcher) {
|
||||
QList<QAbstractEventDispatcher::TimerInfo> timers = eventDispatcher->registeredTimers(this);
|
||||
QList<QAbstractEventDispatcher::TimerInfoV2> timers = eventDispatcher->timersForObject(this);
|
||||
if (!timers.isEmpty()) {
|
||||
const bool res = eventDispatcher->unregisterTimers(this);
|
||||
// do not to release our timer ids back to the pool (since the timer ids are moving to a new thread).
|
||||
|
|
@ -1920,11 +1920,10 @@ int QObject::startTimer(std::chrono::nanoseconds interval, Qt::TimerType timerTy
|
|||
}
|
||||
|
||||
auto dispatcher = thisThreadData->eventDispatcher.loadRelaxed();
|
||||
const auto msecs = std::chrono::ceil<std::chrono::milliseconds>(interval);
|
||||
int timerId = dispatcher->registerTimer(msecs.count(), timerType, this);
|
||||
Qt::TimerId timerId = dispatcher->registerTimer(interval, timerType, this);
|
||||
d->ensureExtraData();
|
||||
d->extraData->runningTimers.append(Qt::TimerId{timerId});
|
||||
return timerId;
|
||||
d->extraData->runningTimers.append(timerId);
|
||||
return int(timerId);
|
||||
}
|
||||
|
||||
/*!
|
||||
|
|
@ -1966,7 +1965,7 @@ void QObject::killTimer(Qt::TimerId id)
|
|||
|
||||
auto thisThreadData = d->threadData.loadRelaxed();
|
||||
if (thisThreadData->hasEventDispatcher())
|
||||
thisThreadData->eventDispatcher.loadRelaxed()->unregisterTimer(qToUnderlying(id));
|
||||
thisThreadData->eventDispatcher.loadRelaxed()->unregisterTimer(id);
|
||||
|
||||
d->extraData->runningTimers.remove(at);
|
||||
QAbstractEventDispatcherPrivate::releaseTimerId(id);
|
||||
|
|
|
|||
|
|
@ -632,7 +632,9 @@ int QTimer::remainingTime() const
|
|||
{
|
||||
Q_D(const QTimer);
|
||||
if (d->isActive()) {
|
||||
return QAbstractEventDispatcher::instance()->remainingTime(qToUnderlying(d->id));
|
||||
using namespace std::chrono;
|
||||
auto remaining = QAbstractEventDispatcher::instance()->remainingTime(d->id);
|
||||
return ceil<milliseconds>(remaining).count();
|
||||
}
|
||||
|
||||
return -1;
|
||||
|
|
|
|||
|
|
@ -22,11 +22,28 @@ static bool glibDisabled = []() {
|
|||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
enum {
|
||||
PreciseTimerInterval = 10,
|
||||
CoarseTimerInterval = 200,
|
||||
VeryCoarseTimerInterval = 1000
|
||||
};
|
||||
static constexpr auto PreciseTimerInterval = 10ms;
|
||||
static constexpr auto CoarseTimerInterval = 200ms;
|
||||
static constexpr auto VeryCoarseTimerInterval = 1s;
|
||||
|
||||
static constexpr
|
||||
std::chrono::nanoseconds fudgeInterval(std::chrono::nanoseconds interval, Qt::TimerType timerType)
|
||||
{
|
||||
// Make the intervals have have fractions of milliseconds so we can check
|
||||
// that they have been rounded & stored properly (where applicable).
|
||||
switch (timerType) {
|
||||
case Qt::VeryCoarseTimer:
|
||||
// rounds down (floor) to seconds
|
||||
return interval + 1010us;
|
||||
case Qt::CoarseTimer:
|
||||
// rounds up (ceil) to milliseconds
|
||||
return interval - 10us;
|
||||
case Qt::PreciseTimer:
|
||||
// not rounded using QAbstractEventDispatcherV2; rounded up (ceil) on V1
|
||||
return interval - 10us;
|
||||
}
|
||||
Q_UNREACHABLE_RETURN(std::chrono::nanoseconds::min());
|
||||
}
|
||||
|
||||
class tst_QEventDispatcher : public QObject
|
||||
{
|
||||
|
|
@ -91,7 +108,7 @@ bool tst_QEventDispatcher::event(QEvent *e)
|
|||
// drain the system event queue after the test starts to avoid destabilizing the test functions
|
||||
void tst_QEventDispatcher::initTestCase()
|
||||
{
|
||||
QDeadlineTimer deadline(CoarseTimerInterval * 1ms);
|
||||
QDeadlineTimer deadline(CoarseTimerInterval);
|
||||
while (!deadline.hasExpired() && eventDispatcher->processEvents(QEventLoop::AllEvents))
|
||||
;
|
||||
}
|
||||
|
|
@ -120,35 +137,36 @@ public:
|
|||
TimerManager(TimerManager &&) = delete;
|
||||
TimerManager &operator=(TimerManager &&) = delete;
|
||||
|
||||
int preciseTimerId() const { return m_preciseTimerId; }
|
||||
int coarseTimerId() const { return m_coarseTimerId; }
|
||||
int veryCoarseTimerId() const { return m_veryCoarseTimerId; }
|
||||
int preciseTimerId() const { return int(m_preciseTimerId); }
|
||||
int coarseTimerId() const { return int(m_coarseTimerId); }
|
||||
int veryCoarseTimerId() const { return int(m_veryCoarseTimerId); }
|
||||
|
||||
bool foundPrecise() const { return m_preciseTimerId > 0; }
|
||||
bool foundCoarse() const { return m_coarseTimerId > 0; }
|
||||
bool foundVeryCoarse() const { return m_veryCoarseTimerId > 0; }
|
||||
bool foundPrecise() const { return preciseTimerId() > 0; }
|
||||
bool foundCoarse() const { return coarseTimerId() > 0; }
|
||||
bool foundVeryCoarse() const { return veryCoarseTimerId() > 0; }
|
||||
|
||||
QList<QAbstractEventDispatcher::TimerInfo> registeredTimers() const
|
||||
QList<QAbstractEventDispatcher::TimerInfoV2> registeredTimers() const
|
||||
{
|
||||
return m_eventDispatcher->registeredTimers(m_parent);
|
||||
return m_eventDispatcher->timersForObject(m_parent);
|
||||
}
|
||||
|
||||
void registerAll()
|
||||
{
|
||||
// start 3 timers, each with the different timer types and different intervals
|
||||
m_preciseTimerId = m_eventDispatcher->registerTimer(
|
||||
PreciseTimerInterval, Qt::PreciseTimer, m_parent);
|
||||
m_coarseTimerId = m_eventDispatcher->registerTimer(
|
||||
CoarseTimerInterval, Qt::CoarseTimer, m_parent);
|
||||
m_veryCoarseTimerId = m_eventDispatcher->registerTimer(
|
||||
VeryCoarseTimerInterval, Qt::VeryCoarseTimer, m_parent);
|
||||
QVERIFY(m_preciseTimerId > 0);
|
||||
QVERIFY(m_coarseTimerId > 0);
|
||||
QVERIFY(m_veryCoarseTimerId > 0);
|
||||
auto registerTimer = [&](std::chrono::milliseconds interval, Qt::TimerType timerType) {
|
||||
return m_eventDispatcher->registerTimer(fudgeInterval(interval, timerType), timerType,
|
||||
m_parent);
|
||||
};
|
||||
m_preciseTimerId = registerTimer(PreciseTimerInterval, Qt::PreciseTimer);
|
||||
m_coarseTimerId = registerTimer(CoarseTimerInterval, Qt::CoarseTimer);
|
||||
m_veryCoarseTimerId = registerTimer(VeryCoarseTimerInterval, Qt::VeryCoarseTimer);
|
||||
QVERIFY(foundPrecise());
|
||||
QVERIFY(foundCoarse());
|
||||
QVERIFY(foundVeryCoarse());
|
||||
findTimers();
|
||||
}
|
||||
|
||||
void unregister(int timerId)
|
||||
void unregister(Qt::TimerId timerId)
|
||||
{
|
||||
m_eventDispatcher->unregisterTimer(timerId);
|
||||
findTimers();
|
||||
|
|
@ -166,36 +184,43 @@ private:
|
|||
bool foundPrecise = false;
|
||||
bool foundCoarse = false;
|
||||
bool foundVeryCoarse = false;
|
||||
const QList<QAbstractEventDispatcher::TimerInfo> timers = registeredTimers();
|
||||
for (int i = 0; i < timers.size(); ++i) {
|
||||
const QAbstractEventDispatcher::TimerInfo &timerInfo = timers.at(i);
|
||||
const QList<QAbstractEventDispatcher::TimerInfoV2> timers = registeredTimers();
|
||||
for (const QAbstractEventDispatcher::TimerInfoV2 &timerInfo : timers) {
|
||||
if (timerInfo.timerId == m_preciseTimerId) {
|
||||
QCOMPARE(timerInfo.interval, int(PreciseTimerInterval));
|
||||
// For precise timers, we expect the fudge factor to be present
|
||||
QAbstractEventDispatcher::Duration interval =
|
||||
fudgeInterval(PreciseTimerInterval, Qt::PreciseTimer);
|
||||
#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0)
|
||||
if (!qobject_cast<QAbstractEventDispatcherV2 *>(m_eventDispatcher))
|
||||
interval = PreciseTimerInterval;
|
||||
#endif
|
||||
QCOMPARE(timerInfo.interval, interval);
|
||||
QCOMPARE(timerInfo.timerType, Qt::PreciseTimer);
|
||||
foundPrecise = true;
|
||||
} else if (timerInfo.timerId == m_coarseTimerId) {
|
||||
QCOMPARE(timerInfo.interval, int(CoarseTimerInterval));
|
||||
// For other timers, the fudge factors ought to have been rounded away
|
||||
QCOMPARE(timerInfo.interval, CoarseTimerInterval);
|
||||
QCOMPARE(timerInfo.timerType, Qt::CoarseTimer);
|
||||
foundCoarse = true;
|
||||
} else if (timerInfo.timerId == m_veryCoarseTimerId) {
|
||||
QCOMPARE(timerInfo.interval, int(VeryCoarseTimerInterval));
|
||||
QCOMPARE(timerInfo.interval, VeryCoarseTimerInterval);
|
||||
QCOMPARE(timerInfo.timerType, Qt::VeryCoarseTimer);
|
||||
foundVeryCoarse = true;
|
||||
}
|
||||
}
|
||||
if (!foundPrecise)
|
||||
m_preciseTimerId = -1;
|
||||
m_preciseTimerId = Qt::TimerId::Invalid;
|
||||
if (!foundCoarse)
|
||||
m_coarseTimerId = -1;
|
||||
m_coarseTimerId = Qt::TimerId::Invalid;
|
||||
if (!foundVeryCoarse)
|
||||
m_veryCoarseTimerId = -1;
|
||||
m_veryCoarseTimerId = Qt::TimerId::Invalid;
|
||||
}
|
||||
|
||||
QAbstractEventDispatcher *m_eventDispatcher = nullptr;
|
||||
|
||||
int m_preciseTimerId = -1;
|
||||
int m_coarseTimerId = -1;
|
||||
int m_veryCoarseTimerId = -1;
|
||||
Qt::TimerId m_preciseTimerId = Qt::TimerId::Invalid;
|
||||
Qt::TimerId m_coarseTimerId = Qt::TimerId::Invalid;
|
||||
Qt::TimerId m_veryCoarseTimerId = Qt::TimerId::Invalid;
|
||||
|
||||
QObject *m_parent = nullptr;
|
||||
};
|
||||
|
|
@ -235,13 +260,13 @@ void tst_QEventDispatcher::registerTimer()
|
|||
if (doubleTimer)
|
||||
QSKIP("Double timer during a single timeout - aborting test as flaky on macOS");
|
||||
if (timerIdFromEvent != timers.preciseTimerId()
|
||||
&& elapsedTimer.elapsed() > PreciseTimerInterval * 3)
|
||||
&& elapsedTimer.durationElapsed() > PreciseTimerInterval * 3)
|
||||
QSKIP("Ignore flaky test behavior due to VM scheduling on macOS");
|
||||
#endif
|
||||
|
||||
QCOMPARE(timerIdFromEvent, timers.preciseTimerId());
|
||||
// now unregister it and make sure it's gone
|
||||
timers.unregister(timers.preciseTimerId());
|
||||
timers.unregister(Qt::TimerId(timers.preciseTimerId()));
|
||||
if (QTest::currentTestFailed())
|
||||
return;
|
||||
QCOMPARE(timers.registeredTimers().size(), 2);
|
||||
|
|
@ -259,13 +284,13 @@ void tst_QEventDispatcher::registerTimer()
|
|||
if (doubleTimer)
|
||||
QSKIP("Double timer during a single timeout - aborting test as flaky on macOS");
|
||||
if (timerIdFromEvent != timers.coarseTimerId()
|
||||
&& elapsedTimer.elapsed() > CoarseTimerInterval * 3)
|
||||
&& elapsedTimer.durationElapsed() > CoarseTimerInterval * 3)
|
||||
QSKIP("Ignore flaky test behavior due to VM scheduling on macOS");
|
||||
#endif
|
||||
|
||||
QCOMPARE(timerIdFromEvent, timers.coarseTimerId());
|
||||
// now unregister it and make sure it's gone
|
||||
timers.unregister(timers.coarseTimerId());
|
||||
timers.unregister(Qt::TimerId(timers.coarseTimerId()));
|
||||
if (QTest::currentTestFailed())
|
||||
return;
|
||||
QCOMPARE(timers.registeredTimers().size(), 1);
|
||||
|
|
|
|||
Loading…
Reference in New Issue