diff options
author | Thiago Macieira <thiago.macieira@intel.com> | 2015-04-16 17:21:37 -0700 |
---|---|---|
committer | Thiago Macieira <thiago.macieira@intel.com> | 2015-07-18 02:24:59 +0000 |
commit | 10c529b08de7cd55b4c3e3654464119246498273 (patch) | |
tree | b2ebe0a8bc1cef7767817b20cf88cda41d6df6c2 /src/corelib/thread | |
parent | 9d98584a835962ca7ad870bbede8f6ab7f66b6bf (diff) |
Add a way for auxiliary threads to handle events without CoreApp
Long-lived threads started by Qt itself can now receive events even if
QCoreApplication hasn't been created. This is required in all threads we
start that will handle events, unless we're sure that the thread will
exit before the global application object begins destruction.
Otherwise, those threads will have race conditions dealing with the
event delivery system trying to call the QCoreApplication::notify()
virtual while the object is being destroyed.
Change-Id: I27eaacb532114dd188c4ffff13d4ad2a4bb443e6
Reviewed-by: Olivier Goffart (Woboq GmbH) <ogoffart@woboq.com>
Diffstat (limited to 'src/corelib/thread')
-rw-r--r-- | src/corelib/thread/qthread.cpp | 27 | ||||
-rw-r--r-- | src/corelib/thread/qthread_p.h | 10 |
2 files changed, 35 insertions, 2 deletions
diff --git a/src/corelib/thread/qthread.cpp b/src/corelib/thread/qthread.cpp index 0c009db930..590479d68c 100644 --- a/src/corelib/thread/qthread.cpp +++ b/src/corelib/thread/qthread.cpp @@ -50,7 +50,8 @@ QT_BEGIN_NAMESPACE QThreadData::QThreadData(int initialRefCount) : _ref(initialRefCount), loopLevel(0), thread(0), threadId(0), - eventDispatcher(0), quitNow(false), canWait(true), isAdopted(false) + eventDispatcher(0), + quitNow(false), canWait(true), isAdopted(false), requiresCoreApplication(true) { // fprintf(stderr, "QThreadData %p created\n", this); } @@ -867,4 +868,28 @@ bool QThread::isInterruptionRequested() const return d->interruptionRequested; } +/*! + \class QDaemonThread + \since 5.5 + \brief The QDaemonThread provides a class to manage threads that outlive QCoreApplication + \internal + + Note: don't try to deliver events from the started() signal. +*/ +static void setThreadDoesNotRequireCoreApplication() +{ + QThreadData::current()->requiresCoreApplication = false; +} + +QDaemonThread::QDaemonThread(QObject *parent) + : QThread(parent) +{ + // QThread::started() is emitted from the thread we start + connect(this, &QThread::started, setThreadDoesNotRequireCoreApplication); +} + +QDaemonThread::~QDaemonThread() +{ +} + QT_END_NAMESPACE diff --git a/src/corelib/thread/qthread_p.h b/src/corelib/thread/qthread_p.h index 1ecd682ad1..ffefe0b1d1 100644 --- a/src/corelib/thread/qthread_p.h +++ b/src/corelib/thread/qthread_p.h @@ -135,6 +135,13 @@ private: #ifndef QT_NO_THREAD +class Q_CORE_EXPORT QDaemonThread : public QThread +{ +public: + QDaemonThread(QObject *parent = 0); + ~QDaemonThread(); +}; + class QThreadPrivate : public QObjectPrivate { Q_DECLARE_PUBLIC(QThread) @@ -224,7 +231,7 @@ public: QThreadData(int initialRefCount = 1); ~QThreadData(); - static QThreadData *current(bool createIfNecessary = true); + static Q_AUTOTEST_EXPORT QThreadData *current(bool createIfNecessary = true); static void clearCurrentThreadData(); static QThreadData *get2(QThread *thread) { Q_ASSERT_X(thread != 0, "QThread", "internal error"); return thread->d_func()->data; } @@ -278,6 +285,7 @@ public: bool quitNow; bool canWait; bool isAdopted; + bool requiresCoreApplication; }; class QScopedLoopLevelCounter |