From 9e1210752f88dc2611de59c75b6b2776794d919a Mon Sep 17 00:00:00 2001 From: Ahmad Samir Date: Sat, 8 Jul 2023 18:52:24 +0300 Subject: [PATCH] QSingleShotTimer: port to chrono Use std::chrono::ceil to match what QDeadlineTimer::remainingTime() did. Drive-by change: make a method private instead of protected, nothing inherits from this class anyway Change-Id: I605b7c25ea7501ee92518ec9f0ff049ed810bfb4 Reviewed-by: Thiago Macieira --- src/corelib/kernel/qsingleshottimer_p.h | 49 ++++++++++++++----------- src/corelib/kernel/qtimer.cpp | 6 ++- 2 files changed, 32 insertions(+), 23 deletions(-) diff --git a/src/corelib/kernel/qsingleshottimer_p.h b/src/corelib/kernel/qsingleshottimer_p.h index 636f209ea17..0a7d7524759 100644 --- a/src/corelib/kernel/qsingleshottimer_p.h +++ b/src/corelib/kernel/qsingleshottimer_p.h @@ -20,6 +20,8 @@ #include "qcoreapplication.h" #include "qmetaobject_p.h" +#include + QT_BEGIN_NAMESPACE class QSingleShotTimer : public QObject @@ -29,31 +31,31 @@ class QSingleShotTimer : public QObject public: inline ~QSingleShotTimer(); - inline QSingleShotTimer(int msec, Qt::TimerType timerType, const QObject *r, + inline QSingleShotTimer(std::chrono::milliseconds msec, Qt::TimerType timerType, const QObject *r, const char *member); - inline QSingleShotTimer(int msec, Qt::TimerType timerType, const QObject *r, + inline QSingleShotTimer(std::chrono::milliseconds msec, Qt::TimerType timerType, const QObject *r, QtPrivate::QSlotObjectBase *slotObj); - inline void startTimerForReceiver(int msec, Qt::TimerType timerType, const QObject *receiver); + inline void startTimerForReceiver(std::chrono::milliseconds msec, Qt::TimerType timerType, + const QObject *receiver); Q_SIGNALS: void timeout(); -protected: +private: inline void timerEvent(QTimerEvent *) override; }; -QSingleShotTimer::QSingleShotTimer(int msec, Qt::TimerType timerType, const QObject *r, - const char *member) +QSingleShotTimer::QSingleShotTimer(std::chrono::milliseconds 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) +QSingleShotTimer::QSingleShotTimer(std::chrono::milliseconds msec, Qt::TimerType timerType, + const QObject *r, QtPrivate::QSlotObjectBase *slotObj) : QObject(QAbstractEventDispatcher::instance()) { int signal_index = QMetaObjectPrivate::signalOffset(&staticMetaObject); @@ -75,8 +77,8 @@ QSingleShotTimer::~QSingleShotTimer() 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) +void QSingleShotTimer::startTimerForReceiver(std::chrono::milliseconds msec, + Qt::TimerType timerType, const QObject *receiver) { if (receiver && receiver->thread() != thread()) { // Avoid leaking the QSingleShotTimer instance in case the application exits before the @@ -86,15 +88,20 @@ void QSingleShotTimer::startTimerForReceiver(int msec, Qt::TimerType timerType, 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); + QDeadlineTimer deadline(msec, timerType); + auto invokable = [this, deadline, timerType] { + if (deadline.hasExpired()) { + Q_EMIT timeout(); + } else { + auto nsecs = deadline.remainingTimeAsDuration(); + // Use std::chrono::ceil to match what + // QDeadlineTimer::remainingTime() did + timerId = startTimer(std::chrono::ceil(nsecs), timerType); + } + }; + QMetaObject::invokeMethod(this, invokable, Qt::QueuedConnection); } else { - timerId = startTimer(std::chrono::milliseconds{msec}, timerType); + timerId = startTimer(msec, timerType); } } @@ -106,7 +113,7 @@ void QSingleShotTimer::timerEvent(QTimerEvent *) killTimer(timerId); timerId = -1; - emit timeout(); + Q_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 @@ -116,4 +123,4 @@ void QSingleShotTimer::timerEvent(QTimerEvent *) QT_END_NAMESPACE -#endif // qsingleshottimer_p.h +#endif // QSINGLESHOTTIMER_P_H diff --git a/src/corelib/kernel/qtimer.cpp b/src/corelib/kernel/qtimer.cpp index 19e80ca6730..90f6dacd428 100644 --- a/src/corelib/kernel/qtimer.cpp +++ b/src/corelib/kernel/qtimer.cpp @@ -15,6 +15,8 @@ #include "qproperty_p.h" #include "qthread.h" +using namespace std::chrono_literals; + QT_BEGIN_NAMESPACE /*! @@ -299,7 +301,7 @@ void QTimer::singleShotImpl(int msec, Qt::TimerType timerType, return; } - new QSingleShotTimer(msec, timerType, receiver, slotObj); + new QSingleShotTimer(msec * 1ms, timerType, receiver, slotObj); } /*! @@ -364,7 +366,7 @@ void QTimer::singleShot(int msec, Qt::TimerType timerType, const QObject *receiv Qt::QueuedConnection); return; } - (void) new QSingleShotTimer(msec, timerType, receiver, member); + (void) new QSingleShotTimer(msec * 1ms, timerType, receiver, member); } }