summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/corelib/CMakeLists.txt1
-rw-r--r--src/corelib/kernel/qsingleshottimer_p.h119
-rw-r--r--src/corelib/kernel/qtimer.cpp86
3 files changed, 121 insertions, 85 deletions
diff --git a/src/corelib/CMakeLists.txt b/src/corelib/CMakeLists.txt
index b19dc8ec82e..9cf67be32fb 100644
--- a/src/corelib/CMakeLists.txt
+++ b/src/corelib/CMakeLists.txt
@@ -181,6 +181,7 @@ qt_internal_add_module(Core
kernel/qsocketnotifier.cpp kernel/qsocketnotifier.h
kernel/qsystemerror.cpp kernel/qsystemerror_p.h
kernel/qtestsupport_core.cpp kernel/qtestsupport_core.h
+ kernel/qsingleshottimer_p.h
kernel/qtimer.cpp kernel/qtimer.h kernel/qtimer_p.h
kernel/qtranslator.cpp kernel/qtranslator.h kernel/qtranslator_p.h
kernel/qvariant.cpp kernel/qvariant.h kernel/qvariant_p.h
diff --git a/src/corelib/kernel/qsingleshottimer_p.h b/src/corelib/kernel/qsingleshottimer_p.h
new file mode 100644
index 00000000000..636f209ea17
--- /dev/null
+++ b/src/corelib/kernel/qsingleshottimer_p.h
@@ -0,0 +1,119 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// Copyright (C) 2016 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QSINGLESHOTTIMER_P_H
+#define QSINGLESHOTTIMER_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qabstracteventdispatcher.h"
+#include "qcoreapplication.h"
+#include "qmetaobject_p.h"
+
+QT_BEGIN_NAMESPACE
+
+class QSingleShotTimer : public QObject
+{
+ Q_OBJECT
+ int timerId = -1;
+
+public:
+ inline ~QSingleShotTimer();
+ inline QSingleShotTimer(int msec, Qt::TimerType timerType, const QObject *r,
+ const char *member);
+ inline QSingleShotTimer(int msec, Qt::TimerType timerType, const QObject *r,
+ QtPrivate::QSlotObjectBase *slotObj);
+
+ inline void startTimerForReceiver(int msec, Qt::TimerType timerType, const QObject *receiver);
+
+Q_SIGNALS:
+ void timeout();
+
+protected:
+ inline void timerEvent(QTimerEvent *) override;
+};
+
+QSingleShotTimer::QSingleShotTimer(int msec, Qt::TimerType timerType, const QObject *r,
+ const char *member)
+ : QObject(QAbstractEventDispatcher::instance())
+{
+ connect(this, SIGNAL(timeout()), r, member);
+
+ startTimerForReceiver(msec, timerType, r);
+}
+
+QSingleShotTimer::QSingleShotTimer(int msec, Qt::TimerType timerType, const QObject *r,
+ QtPrivate::QSlotObjectBase *slotObj)
+ : QObject(QAbstractEventDispatcher::instance())
+{
+ int signal_index = QMetaObjectPrivate::signalOffset(&staticMetaObject);
+ Q_ASSERT(QMetaObjectPrivate::signal(&staticMetaObject, signal_index).name() == "timeout");
+ QObjectPrivate::connectImpl(this, signal_index, r ? r : this, nullptr, slotObj,
+ Qt::AutoConnection, nullptr, &staticMetaObject);
+
+ startTimerForReceiver(msec, timerType, r);
+}
+
+QSingleShotTimer::~QSingleShotTimer()
+{
+ if (timerId > 0)
+ killTimer(timerId);
+}
+
+/*
+ Move the timer, and the dispatching and handling of the timer event, into
+ the same thread as where it will be handled, so that it fires reliably even
+ if the thread that set up the timer is busy.
+*/
+void QSingleShotTimer::startTimerForReceiver(int msec, Qt::TimerType timerType,
+ const QObject *receiver)
+{
+ if (receiver && receiver->thread() != thread()) {
+ // Avoid leaking the QSingleShotTimer instance in case the application exits before the
+ // timer fires
+ connect(QCoreApplication::instance(), &QCoreApplication::aboutToQuit, this,
+ &QObject::deleteLater);
+ setParent(nullptr);
+ moveToThread(receiver->thread());
+
+ QDeadlineTimer deadline(std::chrono::milliseconds{msec}, timerType);
+ QMetaObject::invokeMethod(this, [this, deadline, timerType] {
+ if (deadline.hasExpired())
+ emit timeout();
+ else
+ timerId = startTimer(std::chrono::milliseconds{deadline.remainingTime()}, timerType);
+ }, Qt::QueuedConnection);
+ } else {
+ timerId = startTimer(std::chrono::milliseconds{msec}, timerType);
+ }
+}
+
+void QSingleShotTimer::timerEvent(QTimerEvent *)
+{
+ // need to kill the timer _before_ we emit timeout() in case the
+ // slot connected to timeout calls processEvents()
+ if (timerId > 0)
+ killTimer(timerId);
+ timerId = -1;
+
+ emit timeout();
+
+ // we would like to use delete later here, but it feels like a
+ // waste to post a new event to handle this event, so we just unset the flag
+ // and explicitly delete...
+ qDeleteInEventHandler(this);
+}
+
+QT_END_NAMESPACE
+
+#endif // qsingleshottimer_p.h
diff --git a/src/corelib/kernel/qtimer.cpp b/src/corelib/kernel/qtimer.cpp
index c591b0ecec3..19e80ca6730 100644
--- a/src/corelib/kernel/qtimer.cpp
+++ b/src/corelib/kernel/qtimer.cpp
@@ -4,6 +4,7 @@
#include "qtimer.h"
#include "qtimer_p.h"
+#include "qsingleshottimer_p.h"
#include "qabstracteventdispatcher.h"
#include "qcoreapplication.h"
@@ -253,90 +254,6 @@ void QTimer::timerEvent(QTimerEvent *e)
}
}
-class QSingleShotTimer : public QObject
-{
- Q_OBJECT
- int timerId = -1;
-public:
- ~QSingleShotTimer();
- QSingleShotTimer(int msec, Qt::TimerType timerType, const QObject *r, const char * m);
- QSingleShotTimer(int msec, Qt::TimerType timerType, const QObject *r, QtPrivate::QSlotObjectBase *slotObj);
-
- void startTimerForReceiver(int msec, Qt::TimerType timerType, const QObject *receiver);
-
-Q_SIGNALS:
- void timeout();
-protected:
- void timerEvent(QTimerEvent *) override;
-};
-
-QSingleShotTimer::QSingleShotTimer(int msec, Qt::TimerType timerType, const QObject *r, const char *member)
- : QObject(QAbstractEventDispatcher::instance())
-{
- connect(this, SIGNAL(timeout()), r, member);
-
- startTimerForReceiver(msec, timerType, r);
-}
-
-QSingleShotTimer::QSingleShotTimer(int msec, Qt::TimerType timerType, const QObject *r, QtPrivate::QSlotObjectBase *slotObj)
- : QObject(QAbstractEventDispatcher::instance())
-{
- int signal_index = QMetaObjectPrivate::signalOffset(&staticMetaObject);
- Q_ASSERT(QMetaObjectPrivate::signal(&staticMetaObject, signal_index).name() == "timeout");
- QObjectPrivate::connectImpl(this, signal_index, r ? r : this, nullptr, slotObj,
- Qt::AutoConnection, nullptr, &staticMetaObject);
-
- startTimerForReceiver(msec, timerType, r);
-}
-
-QSingleShotTimer::~QSingleShotTimer()
-{
- if (timerId > 0)
- killTimer(timerId);
-}
-
-/*
- Move the timer, and the dispatching and handling of the timer event, into
- the same thread as where it will be handled, so that it fires reliably even
- if the thread that set up the timer is busy.
-*/
-void QSingleShotTimer::startTimerForReceiver(int msec, Qt::TimerType timerType, const QObject *receiver)
-{
- if (receiver && receiver->thread() != thread()) {
- // Avoid leaking the QSingleShotTimer instance in case the application exits before the timer fires
- connect(QCoreApplication::instance(), &QCoreApplication::aboutToQuit, this, &QObject::deleteLater);
- setParent(nullptr);
- moveToThread(receiver->thread());
-
- QDeadlineTimer deadline(std::chrono::milliseconds{msec}, timerType);
- QMetaObject::invokeMethod(this, [this, deadline, timerType]{
- if (deadline.hasExpired())
- emit timeout();
- else
- timerId = startTimer(std::chrono::milliseconds{deadline.remainingTime()}, timerType);
- }, Qt::QueuedConnection);
- } else {
- timerId = startTimer(std::chrono::milliseconds{msec}, timerType);
- }
-}
-
-
-void QSingleShotTimer::timerEvent(QTimerEvent *)
-{
- // need to kill the timer _before_ we emit timeout() in case the
- // slot connected to timeout calls processEvents()
- if (timerId > 0)
- killTimer(timerId);
- timerId = -1;
-
- emit timeout();
-
- // we would like to use delete later here, but it feels like a
- // waste to post a new event to handle this event, so we just unset the flag
- // and explicitly delete...
- qDeleteInEventHandler(this);
-}
-
/*!
\internal
@@ -699,5 +616,4 @@ QBindable<Qt::TimerType> QTimer::bindableTimerType()
QT_END_NAMESPACE
-#include "qtimer.moc"
#include "moc_qtimer.cpp"