diff options
Diffstat (limited to 'src/corelib/kernel/qtimer.cpp')
-rw-r--r-- | src/corelib/kernel/qtimer.cpp | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/src/corelib/kernel/qtimer.cpp b/src/corelib/kernel/qtimer.cpp index 13f027074a..188d529f04 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); } |