diff options
Diffstat (limited to 'src/corelib/kernel/qtimer.cpp')
-rw-r--r-- | src/corelib/kernel/qtimer.cpp | 33 |
1 files changed, 31 insertions, 2 deletions
diff --git a/src/corelib/kernel/qtimer.cpp b/src/corelib/kernel/qtimer.cpp index 9d3bd5fdbf..948f697dc5 100644 --- a/src/corelib/kernel/qtimer.cpp +++ b/src/corelib/kernel/qtimer.cpp @@ -42,6 +42,8 @@ #include "qabstracteventdispatcher.h" #include "qcoreapplication.h" #include "qobject_p.h" +#include "qthread.h" +#include "qcoreapplication_p.h" QT_BEGIN_NAMESPACE @@ -343,6 +345,33 @@ void QTimer::singleShotImpl(int msec, Qt::TimerType timerType, const QObject *receiver, QtPrivate::QSlotObjectBase *slotObj) { + if (msec == 0) { + bool deleteReceiver = false; + // Optimize: set a receiver context when none is given, such that we can use + // QMetaObject::invokeMethod which is more efficient than going through a timer. + // We need a QObject living in the current thread. But the QThread itself lives + // in a different thread - with the exception of the main QThread which lives in + // itself. And QThread::currentThread() is among the few QObjects we know that will + // most certainly be there. Note that one can actually call singleShot before the + // QApplication is created! + if (!receiver && QThread::currentThread() == QCoreApplicationPrivate::mainThread()) { + // reuse main thread as context object + receiver = QThread::currentThread(); + } else if (!receiver) { + // Create a receiver context object on-demand. According to the benchmarks, + // this is still more efficient than going through a timer. + receiver = new QObject; + deleteReceiver = true; + } + + QMetaObject::invokeMethodImpl(const_cast<QObject *>(receiver), slotObj, + Qt::QueuedConnection, nullptr); + + if (deleteReceiver) + const_cast<QObject *>(receiver)->deleteLater(); + return; + } + new QSingleShotTimer(msec, timerType, receiver, slotObj); } @@ -575,8 +604,8 @@ void QTimer::singleShot(int msec, Qt::TimerType timerType, const QObject *receiv \since 5.12 \overload - Creates a connection from the timeout() signal to \a slot, and returns a - handle to the connection. + Creates a connection of type \a connectionType from the timeout() signal + to \a slot, and returns a handle to the connection. This method is provided for convenience. It's equivalent to calling \c {QObject::connect(timer, &QTimer::timeout, timer, slot, connectionType)}. |