diff options
Diffstat (limited to 'src/corelib/thread')
-rw-r--r-- | src/corelib/thread/qmutex.cpp | 6 | ||||
-rw-r--r-- | src/corelib/thread/qmutex_p.h | 6 | ||||
-rw-r--r-- | src/corelib/thread/qthread.cpp | 9 | ||||
-rw-r--r-- | src/corelib/thread/qthread.h | 2 | ||||
-rw-r--r-- | src/corelib/thread/qthread_p.h | 17 | ||||
-rw-r--r-- | src/corelib/thread/qthread_win.cpp | 31 |
6 files changed, 57 insertions, 14 deletions
diff --git a/src/corelib/thread/qmutex.cpp b/src/corelib/thread/qmutex.cpp index e13c78636c..049230f7a4 100644 --- a/src/corelib/thread/qmutex.cpp +++ b/src/corelib/thread/qmutex.cpp @@ -49,7 +49,7 @@ #include "qthread.h" #include "qmutex_p.h" -#ifndef Q_MUTEX_LINUX +#ifndef QT_LINUX_FUTEX #include "private/qfreelist_p.h" #endif @@ -154,7 +154,7 @@ QMutex::~QMutex() if (quintptr(d) > 0x3 && d->recursive) { delete static_cast<QRecursiveMutexPrivate *>(d); } else if (d) { -#ifndef Q_MUTEX_LINUX +#ifndef QT_LINUX_FUTEX if (d != dummyLocked() && static_cast<QMutexPrivate *>(d)->possiblyUnlocked.load() && tryLock()) { unlock(); @@ -340,7 +340,7 @@ bool QBasicMutex::isRecursive() { \sa unlock() */ -#ifndef Q_MUTEX_LINUX //linux implementation is in qmutex_linux.cpp +#ifndef QT_LINUX_FUTEX //linux implementation is in qmutex_linux.cpp /*! \internal helper for lock() */ diff --git a/src/corelib/thread/qmutex_p.h b/src/corelib/thread/qmutex_p.h index 8a9d0bf39b..92f13b1b7d 100644 --- a/src/corelib/thread/qmutex_p.h +++ b/src/corelib/thread/qmutex_p.h @@ -65,7 +65,7 @@ #if defined(Q_OS_LINUX) && !defined(QT_LINUXBASE) // use Linux mutexes everywhere except for LSB builds -# define Q_MUTEX_LINUX +# define QT_LINUX_FUTEX #endif QT_BEGIN_NAMESPACE @@ -78,7 +78,7 @@ public: : recursive(mode == QMutex::Recursive) {} }; -#if !defined(Q_MUTEX_LINUX) +#if !defined(QT_LINUX_FUTEX) class QMutexPrivate : public QMutexData { public: @@ -128,7 +128,7 @@ public: Qt::HANDLE event; #endif }; -#endif //Q_MUTEX_LINUX +#endif //QT_LINUX_FUTEX class QRecursiveMutexPrivate : public QMutexData { 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) }; diff --git a/src/corelib/thread/qthread_win.cpp b/src/corelib/thread/qthread_win.cpp index bdee6d6b7c..38fb6ef8dd 100644 --- a/src/corelib/thread/qthread_win.cpp +++ b/src/corelib/thread/qthread_win.cpp @@ -72,7 +72,7 @@ QT_BEGIN_NAMESPACE void qt_watch_adopted_thread(const HANDLE adoptedThreadHandle, QThread *qthread); -void qt_adopted_thread_watcher_function(void *); +DWORD WINAPI qt_adopted_thread_watcher_function(LPVOID); static DWORD qt_current_thread_data_tls_index = TLS_OUT_OF_INDEXES; void qt_create_tls() @@ -147,7 +147,7 @@ void QAdoptedThread::init() static QVector<HANDLE> qt_adopted_thread_handles; static QVector<QThread *> qt_adopted_qthreads; static QMutex qt_adopted_thread_watcher_mutex; -static HANDLE qt_adopted_thread_watcher_handle = 0; +static DWORD qt_adopted_thread_watcher_id = 0; static HANDLE qt_adopted_thread_wakeup = 0; /*! \internal @@ -158,18 +158,25 @@ static HANDLE qt_adopted_thread_wakeup = 0; void qt_watch_adopted_thread(const HANDLE adoptedThreadHandle, QThread *qthread) { QMutexLocker lock(&qt_adopted_thread_watcher_mutex); + + if (GetCurrentThreadId() == qt_adopted_thread_watcher_id) { +#if !defined(Q_OS_WINCE) || (defined(_WIN32_WCE) && (_WIN32_WCE>=0x600)) + CloseHandle(adoptedThreadHandle); +#endif + return; + } + qt_adopted_thread_handles.append(adoptedThreadHandle); qt_adopted_qthreads.append(qthread); // Start watcher thread if it is not already running. - if (qt_adopted_thread_watcher_handle == 0) { + if (qt_adopted_thread_watcher_id == 0) { if (qt_adopted_thread_wakeup == 0) { qt_adopted_thread_wakeup = CreateEvent(0, false, false, 0); qt_adopted_thread_handles.prepend(qt_adopted_thread_wakeup); } - qt_adopted_thread_watcher_handle = - (HANDLE)_beginthread(qt_adopted_thread_watcher_function, 0, NULL); + CreateThread(0, 0, qt_adopted_thread_watcher_function, 0, 0, &qt_adopted_thread_watcher_id); } else { SetEvent(qt_adopted_thread_wakeup); } @@ -180,13 +187,13 @@ void qt_watch_adopted_thread(const HANDLE adoptedThreadHandle, QThread *qthread) When this happens it derefs the QThreadData for the adopted thread to make sure it gets cleaned up properly. */ -void qt_adopted_thread_watcher_function(void *) +DWORD WINAPI qt_adopted_thread_watcher_function(LPVOID) { forever { qt_adopted_thread_watcher_mutex.lock(); if (qt_adopted_thread_handles.count() == 1) { - qt_adopted_thread_watcher_handle = 0; + qt_adopted_thread_watcher_id = 0; qt_adopted_thread_watcher_mutex.unlock(); break; } @@ -224,7 +231,9 @@ void qt_adopted_thread_watcher_function(void *) // printf("(qt) - qt_adopted_thread_watcher_function... called\n"); const int qthreadIndex = handleIndex - 1; + qt_adopted_thread_watcher_mutex.lock(); QThreadData *data = QThreadData::get2(qt_adopted_qthreads.at(qthreadIndex)); + qt_adopted_thread_watcher_mutex.unlock(); if (data->isAdopted) { QThread *thread = data->thread; Q_ASSERT(thread); @@ -234,14 +243,20 @@ void qt_adopted_thread_watcher_function(void *) } data->deref(); + QMutexLocker lock(&qt_adopted_thread_watcher_mutex); #if !defined(Q_OS_WINCE) || (defined(_WIN32_WCE) && (_WIN32_WCE>=0x600)) CloseHandle(qt_adopted_thread_handles.at(handleIndex)); #endif - QMutexLocker lock(&qt_adopted_thread_watcher_mutex); qt_adopted_thread_handles.remove(handleIndex); qt_adopted_qthreads.remove(qthreadIndex); } } + + QThreadData *threadData = reinterpret_cast<QThreadData *>(TlsGetValue(qt_current_thread_data_tls_index)); + if (threadData) + threadData->deref(); + + return 0; } #if !defined(QT_NO_DEBUG) && defined(Q_CC_MSVC) && !defined(Q_OS_WINCE) |