summaryrefslogtreecommitdiffstats
path: root/src/corelib/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/kernel')
-rw-r--r--src/corelib/kernel/qcoreapplication.cpp28
-rw-r--r--src/corelib/kernel/qcoreapplication_p.h2
-rw-r--r--src/corelib/kernel/qeventloop.cpp2
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);