summaryrefslogtreecommitdiffstats
path: root/src/corelib/thread
diff options
context:
space:
mode:
authorTor Arne Vestbø <tor.arne.vestbo@digia.com>2013-06-11 13:05:13 (GMT)
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-06-16 10:39:19 (GMT)
commit8d23f522c29dc2983cf2eae46a9259da326fc8b5 (patch)
tree877a531eae4a50af3996ccbc8b7e6c7303f2013c /src/corelib/thread
parentbd42c14963f1434eb8ca7ba2a432a2f9f970f80a (diff)
downloadQt-8d23f522c29dc2983cf2eae46a9259da326fc8b5.zip
Qt-8d23f522c29dc2983cf2eae46a9259da326fc8b5.tar.gz
Qt-8d23f522c29dc2983cf2eae46a9259da326fc8b5.tar.bz2
Fix crash when re-creating QThreadData after initially destroying it
We destroy the thread data for the main thread when the QCoreApplication is destructed, and then delete the pthread key for the thread data in the global static destructor function 'destroy_current_thread_data_key'. The user may have its own Q_DESTRUCTOR_FUNCTION though, which may or may not run after we've destroyed the key. If it runs after we've destroyed the key, we'll end up trying to re-create the tread-data, as expected, but set_thread_data() will fail to persist it, as pthread_setspecific is called with an invalid key. The result is an infinite recursion: ... 6 in QThreadData::current () at qthread_unix.cpp:216 7 in QObject::QObject (this=0x48e1b30, dd=@0x48e1b40, parent=0x0) at qobject.cpp:703 8 in QThread::QThread (this=0x48e1b30, dd=@0x48e1b40, parent=0x0) at qthread.cpp:396 9 in QAdoptedThread::QAdoptedThread (this=0x48e1b30, data=0x48e1af0) at qthread.cpp:120 10 in QAdoptedThread::QAdoptedThread (this=0x48e1b30, data=0x48e1af0) at qthread.cpp:130 11 in QThreadData::current () at qthread_unix.cpp:219 12 in QObject::QObject (this=0x48e1a20, dd=@0x48e1a30, parent=0x0) at qobject.cpp:703 ... To solve this, we reset current_thread_data_once when destroying the key, so that subsequent calls to pthread_once to potentially create the key will call create_current_thread_data_key once more. This means we'll leak the key for this particular use-case, since we don't end up calling pthread_key_delete a second time, but this leak is small and happens typically only for a short duration during application shutdown. Cherry-picked from qtbase/46667d604fb2ae11a87c0c075a3d2468d02f7bdb. Change-Id: Iffc372ca530a486cd3efc2237ab02468bdcb5c81 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'src/corelib/thread')
-rw-r--r--src/corelib/thread/qthread_unix.cpp6
1 files changed, 6 insertions, 0 deletions
diff --git a/src/corelib/thread/qthread_unix.cpp b/src/corelib/thread/qthread_unix.cpp
index 57127a2..d3c0050 100644
--- a/src/corelib/thread/qthread_unix.cpp
+++ b/src/corelib/thread/qthread_unix.cpp
@@ -171,6 +171,12 @@ static void destroy_current_thread_data_key()
{
pthread_once(&current_thread_data_once, create_current_thread_data_key);
pthread_key_delete(current_thread_data_key);
+
+ // Reset current_thread_data_once in case we end up recreating
+ // the thread-data in the rare case of QObject construction
+ // after destroying the QThreadData.
+ pthread_once_t pthread_once_init = PTHREAD_ONCE_INIT;
+ current_thread_data_once = pthread_once_init;
}
Q_DESTRUCTOR_FUNCTION(destroy_current_thread_data_key)