diff options
author | Ivan Solovev <ivan.solovev@qt.io> | 2024-02-08 17:19:26 +0100 |
---|---|---|
committer | Ivan Solovev <ivan.solovev@qt.io> | 2024-02-12 23:49:54 +0100 |
commit | 612b67cf13cedb832e082308b620f948377ddf21 (patch) | |
tree | 8d636fbfeb8a2873d807239d63199e630c8863a1 /src/corelib/kernel/qtimer.cpp | |
parent | 9f66c9396f2dfd96e8b73ae34c75f168254d7bd6 (diff) |
QTimer: do not set active state when setting a negative interval
QObject::startTimer() returns 0 in case of failure, for example when
someone tries to register a timer with a negative interval.
However, QTimer internally uses -1 as an invalid timer id.
This could lead to a situation when the timer was not really started,
but QTimer::isActive() returned true.
This patch fixes it in two ways:
- check the return value of QObject::startTimer() and treat 0 as an
error.
- do not treat 0 as a valid timer id when calculating the active state.
As a drive-by: move the `using namespace std::chrono_literals;`
declaration to the top of tst_qtimer.cpp, so that we do not need to
repeat it in each test case.
Fixes: QTBUG-122087
Pick-to: 6.7 6.6 6.5
Change-Id: I0e21152b2173ebb5fb0dada1b99a903a321ca9c4
Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>
Diffstat (limited to 'src/corelib/kernel/qtimer.cpp')
-rw-r--r-- | src/corelib/kernel/qtimer.cpp | 20 |
1 files changed, 15 insertions, 5 deletions
diff --git a/src/corelib/kernel/qtimer.cpp b/src/corelib/kernel/qtimer.cpp index 90f6dacd42..04e32d9ec7 100644 --- a/src/corelib/kernel/qtimer.cpp +++ b/src/corelib/kernel/qtimer.cpp @@ -192,8 +192,11 @@ void QTimer::start() Q_D(QTimer); if (d->id != QTimerPrivate::INV_TIMER) // stop running timer stop(); - d->id = QObject::startTimer(std::chrono::milliseconds{d->inter}, d->type); - d->isActiveData.notify(); + const int id = QObject::startTimer(std::chrono::milliseconds{d->inter}, d->type); + if (id > 0) { + d->id = id; + d->isActiveData.notify(); + } } /*! @@ -554,9 +557,16 @@ void QTimer::setInterval(int msec) d->inter.setValueBypassingBindings(msec); if (d->id != QTimerPrivate::INV_TIMER) { // create new timer QObject::killTimer(d->id); // restart timer - d->id = QObject::startTimer(std::chrono::milliseconds{msec}, d->type); - // No need to call markDirty() for d->isActiveData here, - // as timer state actually does not change + const int id = QObject::startTimer(std::chrono::milliseconds{msec}, d->type); + if (id > 0) { + // Restarted successfully. No need to update the active state. + d->id = id; + } else { + // Failed to start the timer. + // Need to notify about active state change. + d->id = QTimerPrivate::INV_TIMER; + d->isActiveData.notify(); + } } if (intervalChanged) d->inter.notify(); |