diff options
Diffstat (limited to 'src/corelib/kernel')
-rw-r--r-- | src/corelib/kernel/qcoreapplication.cpp | 28 | ||||
-rw-r--r-- | src/corelib/kernel/qcoreapplication_p.h | 2 | ||||
-rw-r--r-- | src/corelib/kernel/qeventloop.cpp | 2 |
3 files changed, 28 insertions, 4 deletions
diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp index e47dc0dff2..9ad7970807 100644 --- a/src/corelib/kernel/qcoreapplication.cpp +++ b/src/corelib/kernel/qcoreapplication.cpp @@ -538,6 +538,14 @@ QThread *QCoreApplicationPrivate::mainThread() return theMainThread; } +bool QCoreApplicationPrivate::threadRequiresCoreApplication() +{ + QThreadData *data = QThreadData::current(false); + if (!data) + return true; // default setting + return data->requiresCoreApplication; +} + void QCoreApplicationPrivate::checkReceiverThread(QObject *receiver) { QThread *currentThread = QThread::currentThread(); @@ -926,6 +934,8 @@ bool QCoreApplication::isQuitLockEnabled() return quitLockRefEnabled; } +static bool doNotify(QObject *, QEvent *); + /*! Enables the ability of the QEventLoopLocker feature to quit the application. @@ -960,7 +970,8 @@ bool QCoreApplication::notifyInternal(QObject *receiver, QEvent *event) */ bool QCoreApplication::notifyInternal2(QObject *receiver, QEvent *event) { - if (!self) + bool selfRequired = QCoreApplicationPrivate::threadRequiresCoreApplication(); + if (!self && selfRequired) return false; // Make it possible for Qt Script to hook into events even @@ -978,6 +989,8 @@ bool QCoreApplication::notifyInternal2(QObject *receiver, QEvent *event) QObjectPrivate *d = receiver->d_func(); QThreadData *threadData = d->threadData; QScopedLoopLevelCounter loopLevelCounter(threadData); + if (!selfRequired) + return doNotify(receiver, event); return self->notify(receiver, event); } @@ -1039,7 +1052,11 @@ bool QCoreApplication::notify(QObject *receiver, QEvent *event) // no events are delivered after ~QCoreApplication() has started if (QCoreApplicationPrivate::is_app_closing) return true; + return doNotify(receiver, event); +} +static bool doNotify(QObject *receiver, QEvent *event) +{ if (receiver == 0) { // serious error qWarning("QCoreApplication::notify: Unexpected null receiver"); return true; @@ -1054,7 +1071,10 @@ bool QCoreApplication::notify(QObject *receiver, QEvent *event) bool QCoreApplicationPrivate::sendThroughApplicationEventFilters(QObject *receiver, QEvent *event) { - if (receiver->d_func()->threadData == this->threadData && extraData) { + // We can't access the application event filters outside of the main thread (race conditions) + Q_ASSERT(receiver->d_func()->threadData->thread == mainThread()); + + if (extraData) { // application event filters are only called for objects in the GUI thread for (int i = 0; i < extraData->eventFilters.size(); ++i) { QObject *obj = extraData->eventFilters.at(i); @@ -1097,7 +1117,9 @@ bool QCoreApplicationPrivate::sendThroughObjectEventFilters(QObject *receiver, Q bool QCoreApplicationPrivate::notify_helper(QObject *receiver, QEvent * event) { // send to all application event filters (only does anything in the main thread) - if (QCoreApplication::self->d_func()->sendThroughApplicationEventFilters(receiver, event)) + if (QCoreApplication::self + && receiver->d_func()->threadData->thread == mainThread() + && QCoreApplication::self->d_func()->sendThroughApplicationEventFilters(receiver, event)) return true; // send to all receiver event filters if (sendThroughObjectEventFilters(receiver, event)) diff --git a/src/corelib/kernel/qcoreapplication_p.h b/src/corelib/kernel/qcoreapplication_p.h index 5fed850c2b..21f59d8197 100644 --- a/src/corelib/kernel/qcoreapplication_p.h +++ b/src/corelib/kernel/qcoreapplication_p.h @@ -107,6 +107,8 @@ public: static QThread *theMainThread; static QThread *mainThread(); + static bool threadRequiresCoreApplication(); + static void sendPostedEvents(QObject *receiver, int event_type, QThreadData *data); static void checkReceiverThread(QObject *receiver); diff --git a/src/corelib/kernel/qeventloop.cpp b/src/corelib/kernel/qeventloop.cpp index 1723db0ab9..dca25ce968 100644 --- a/src/corelib/kernel/qeventloop.cpp +++ b/src/corelib/kernel/qeventloop.cpp @@ -93,7 +93,7 @@ QEventLoop::QEventLoop(QObject *parent) : QObject(*new QEventLoopPrivate, parent) { Q_D(QEventLoop); - if (!QCoreApplication::instance()) { + if (!QCoreApplication::instance() && QCoreApplicationPrivate::threadRequiresCoreApplication()) { qWarning("QEventLoop: Cannot be used without QApplication"); } else if (!d->threadData->eventDispatcher.load()) { QThreadPrivate::createEventDispatcher(d->threadData); |