From b067f6cfe30a5a687316130d04678ac406837d09 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Wed, 8 Feb 2012 15:55:29 +0100 Subject: Add the quitlock feature to QThread. Change-Id: Ib44ee9739499ba4c5f0fecbef3976251ea22836d Reviewed-by: Bradley T. Hughes Reviewed-by: Thiago Macieira --- src/corelib/kernel/qeventloop.cpp | 19 +++++++++++++++++-- src/corelib/kernel/qeventloop.h | 1 + src/corelib/thread/qthread.cpp | 9 +++++++++ src/corelib/thread/qthread.h | 2 ++ src/corelib/thread/qthread_p.h | 17 +++++++++++++++++ 5 files changed, 46 insertions(+), 2 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/kernel/qeventloop.cpp b/src/corelib/kernel/qeventloop.cpp index 8b0ec85679..2fb351797c 100644 --- a/src/corelib/kernel/qeventloop.cpp +++ b/src/corelib/kernel/qeventloop.cpp @@ -322,13 +322,19 @@ class QEventLoopLockerPrivate { public: explicit QEventLoopLockerPrivate(QEventLoopPrivate *loop) - : loop(loop), app(0) + : loop(loop), thread(0), app(0) { loop->ref(); } + explicit QEventLoopLockerPrivate(QThreadPrivate *thread) + : loop(0), thread(thread), app(0) + { + thread->ref(); + } + explicit QEventLoopLockerPrivate(QCoreApplicationPrivate *app) - : loop(0), app(app) + : loop(0), thread(0), app(app) { app->ref(); } @@ -337,12 +343,15 @@ public: { if (loop) loop->deref(); + else if (thread) + thread->deref(); else app->deref(); } private: QEventLoopPrivate *loop; + QThreadPrivate *thread; QCoreApplicationPrivate *app; }; @@ -390,6 +399,12 @@ QEventLoopLocker::QEventLoopLocker(QEventLoop *loop) } +QEventLoopLocker::QEventLoopLocker(QThread *thread) + : d_ptr(new QEventLoopLockerPrivate(static_cast(QObjectPrivate::get(thread)))) +{ + +} + /*! Destroys this event loop locker object */ diff --git a/src/corelib/kernel/qeventloop.h b/src/corelib/kernel/qeventloop.h index 0e7195d6a7..ba082d7d9d 100644 --- a/src/corelib/kernel/qeventloop.h +++ b/src/corelib/kernel/qeventloop.h @@ -96,6 +96,7 @@ class Q_CORE_EXPORT QEventLoopLocker public: QEventLoopLocker(); explicit QEventLoopLocker(QEventLoop *loop); + explicit QEventLoopLocker(QThread *thread); ~QEventLoopLocker(); private: diff --git a/src/corelib/thread/qthread.cpp b/src/corelib/thread/qthread.cpp index be0a98d3b5..a071463178 100644 --- a/src/corelib/thread/qthread.cpp +++ b/src/corelib/thread/qthread.cpp @@ -763,5 +763,14 @@ void QThread::setEventDispatcher(QAbstractEventDispatcher *eventDispatcher) } } +bool QThread::event(QEvent *event) +{ + if (event->type() == QEvent::Quit) { + quit(); + return true; + } else { + return QObject::event(event); + } +} QT_END_NAMESPACE diff --git a/src/corelib/thread/qthread.h b/src/corelib/thread/qthread.h index 719f4afbbb..ba119afb5d 100644 --- a/src/corelib/thread/qthread.h +++ b/src/corelib/thread/qthread.h @@ -95,6 +95,8 @@ public: QAbstractEventDispatcher *eventDispatcher() const; void setEventDispatcher(QAbstractEventDispatcher *eventDispatcher); + bool event(QEvent *event); + public Q_SLOTS: void start(Priority = InheritPriority); void terminate(); diff --git a/src/corelib/thread/qthread_p.h b/src/corelib/thread/qthread_p.h index d8374e9805..6597b56893 100644 --- a/src/corelib/thread/qthread_p.h +++ b/src/corelib/thread/qthread_p.h @@ -60,6 +60,7 @@ #include "QtCore/qstack.h" #include "QtCore/qwaitcondition.h" #include "QtCore/qmap.h" +#include "QtCore/qcoreapplication.h" #include "private/qobject_p.h" @@ -144,6 +145,7 @@ public: ~QThreadPrivate(); mutable QMutex mutex; + QAtomicInt quitLockRef; bool running; bool finished; @@ -179,6 +181,18 @@ public: QThreadData *data; static void createEventDispatcher(QThreadData *data); + + void ref() + { + quitLockRef.ref(); + } + + void deref() + { + if (!quitLockRef.deref() && running) { + QCoreApplication::instance()->postEvent(q_ptr, new QEvent(QEvent::Quit)); + } + } }; #else // QT_NO_THREAD @@ -195,6 +209,9 @@ public: static QThread *threadForId(int) { return QThread::currentThread(); } static void createEventDispatcher(QThreadData *data); + void ref() {} + void deref() {} + Q_DECLARE_PUBLIC(QThread) }; -- cgit v1.2.3