QTimerInfoList: refactor unregisterTimers()

- Use removeIf(), easier to reason about than removing from the list
  during iteration
- Return true only if any timers were actually unregistered
- Assert in QObject::event() that if the list returned by
  eventDispatcher->registeredTimers() isn't empty, then
  eventDispatcher->unregisteredTimers() returns true

Change-Id: I739a3865b7524a7aab3ff0227e6a060ed98d6191
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
Ahmad Samir 2023-07-10 17:45:17 +03:00
parent fa42350c8d
commit 74422bbf02
2 changed files with 21 additions and 16 deletions

View File

@ -1415,8 +1415,11 @@ bool QObject::event(QEvent *e)
if (eventDispatcher) {
QList<QAbstractEventDispatcher::TimerInfo> timers = eventDispatcher->registeredTimers(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).
eventDispatcher->unregisterTimers(this);
Q_ASSERT_X(res, Q_FUNC_INFO,
"QAbstractEventDispatcher::unregisterTimers() returned false,"
" but there are timers associated with this object.");
QMetaObject::invokeMethod(this, "_q_reregisterTimers", Qt::QueuedConnection,
Q_ARG(void*, (new QList<QAbstractEventDispatcher::TimerInfo>(timers))));
}

View File

@ -353,22 +353,24 @@ bool QTimerInfoList::unregisterTimers(QObject *object)
{
if (isEmpty())
return false;
for (int i = 0; i < size(); ++i) {
QTimerInfo *t = at(i);
if (t->obj == object) {
// object found
removeAt(i);
auto associatedWith = [this](QObject *o) {
return [this, o](auto &t) {
if (t->obj == o) {
if (t == firstTimerInfo)
firstTimerInfo = nullptr;
if (t->activateRef)
*(t->activateRef) = nullptr;
delete t;
// move back one so that we don't skip the new current item
--i;
}
}
return true;
}
return false;
};
};
qsizetype count = removeIf(associatedWith(object));
return count > 0;
}
QList<QAbstractEventDispatcher::TimerInfo> QTimerInfoList::registeredTimers(QObject *object) const
{