summaryrefslogtreecommitdiffstats
path: root/src/corelib/kernel/qtimer.cpp
diff options
context:
space:
mode:
authorIvan Solovev <ivan.solovev@qt.io>2024-02-08 17:19:26 +0100
committerIvan Solovev <ivan.solovev@qt.io>2024-02-12 23:49:54 +0100
commit612b67cf13cedb832e082308b620f948377ddf21 (patch)
tree8d636fbfeb8a2873d807239d63199e630c8863a1 /src/corelib/kernel/qtimer.cpp
parent9f66c9396f2dfd96e8b73ae34c75f168254d7bd6 (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.cpp20
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();