diff options
author | jian liang <jianliang79@gmail.com> | 2012-02-18 00:43:29 (GMT) |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2012-02-28 14:35:06 (GMT) |
commit | 91cf813c816582188ef8943b29338c3db06d1133 (patch) | |
tree | 923ed21e0885867531485199a106089c018a885c /src/corelib/thread/qthread_win.cpp | |
parent | 50ad6db629ecd268192023ad97577c51c9b19c32 (diff) | |
download | Qt-91cf813c816582188ef8943b29338c3db06d1133.zip Qt-91cf813c816582188ef8943b29338c3db06d1133.tar.gz Qt-91cf813c816582188ef8943b29338c3db06d1133.tar.bz2 |
Fix to exit of adopted thread watcher in Windows
Don't register the thread handle and QThread object pointer to watch list
for adopted thread watcher thread in Windows. Otherwise the watcher thread
will never exit and can't clean up its own QThreadData and QAdoptedThread
object.
Task-number: QTBUG-23961
Change-Id: Ia84326cf3cfd978d2b003ccc1bb6861db950e899
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@nokia.com>
Reviewed-by: Joerg Bornemann <joerg.bornemann@nokia.com>
(cherry picked from commit bf66eebbc28b1f405a49a68d3f6c341d433159ea)
Diffstat (limited to 'src/corelib/thread/qthread_win.cpp')
-rw-r--r-- | src/corelib/thread/qthread_win.cpp | 27 |
1 files changed, 20 insertions, 7 deletions
diff --git a/src/corelib/thread/qthread_win.cpp b/src/corelib/thread/qthread_win.cpp index 4dc7b63..e8ad26e 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() @@ -157,7 +157,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 @@ -168,18 +168,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); } @@ -190,13 +197,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; } @@ -254,6 +261,12 @@ void qt_adopted_thread_watcher_function(void *) 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) |