diff options
author | Mike Achtelik <mike.achtelik@gmail.com> | 2020-07-03 10:13:58 +0200 |
---|---|---|
committer | Mike Achtelik <mike.achtelik@gmail.com> | 2020-07-04 17:56:11 +0200 |
commit | 90f1ef14aaf2f4b4dc49755ab8605e6a37ee06c6 (patch) | |
tree | f63c0a0d743cddd3072b87ce91ac6c1a169fcd7d /src/corelib | |
parent | f172f0dee931821991905879d03c01a409975983 (diff) |
Fix workaround in pthread destructor
Amends dcdfb6908db0f83cbc4e550859f56ee58a6b3420 which failed to take the
workaround in destroy_current_thread_data into account.
Since pthread_getspecific was completely replaced with the thread_local variable
currentThreadData, the workaround has no effect anymore. Therefore we need to
replace it with a workaround that makes sure currentThreadData is set inside of
the destructor function.
This prevents a leak, where QThreadPrivate::finish() tries to access the
thread data, but since it already is null, recreates it without ever deleting it.
Pick-to: 5.15
Change-Id: I3811d262a411a6bde9d6eb90f8d17e0bbc5de657
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'src/corelib')
-rw-r--r-- | src/corelib/thread/qthread_unix.cpp | 25 |
1 files changed, 6 insertions, 19 deletions
diff --git a/src/corelib/thread/qthread_unix.cpp b/src/corelib/thread/qthread_unix.cpp index 35bfd35f1a..5f182df10e 100644 --- a/src/corelib/thread/qthread_unix.cpp +++ b/src/corelib/thread/qthread_unix.cpp @@ -116,18 +116,11 @@ static pthread_key_t current_thread_data_key; static void destroy_current_thread_data(void *p) { -#if defined(Q_OS_VXWORKS) - // Calling setspecific(..., 0) sets the value to 0 for ALL threads. - // The 'set to 1' workaround adds a bit of an overhead though, - // since this function is called twice now. - if (p == (void *)1) - return; -#endif - // POSIX says the value in our key is set to zero before calling - // this destructor function, so we need to set it back to the - // right value... - pthread_setspecific(current_thread_data_key, p); QThreadData *data = static_cast<QThreadData *>(p); + // thread_local variables are set to zero before calling this destructor function, + // if they are internally using pthread-specific data management, + // so we need to set it back to the right value... + currentThreadData = data; if (data->isAdopted) { QThread *thread = data->thread.loadAcquire(); Q_ASSERT(thread); @@ -138,14 +131,8 @@ static void destroy_current_thread_data(void *p) data->deref(); // ... but we must reset it to zero before returning so we aren't - // called again (POSIX allows implementations to call destructor - // functions repeatedly until all values are zero) - pthread_setspecific(current_thread_data_key, -#if defined(Q_OS_VXWORKS) - (void *)1); -#else - nullptr); -#endif + // leaving a dangling pointer. + currentThreadData = nullptr; } static void create_current_thread_data_key() |