summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMike Achtelik <mike.achtelik@gmail.com>2020-07-03 10:13:58 +0200
committerMike Achtelik <mike.achtelik@gmail.com>2020-07-04 17:56:11 +0200
commit90f1ef14aaf2f4b4dc49755ab8605e6a37ee06c6 (patch)
treef63c0a0d743cddd3072b87ce91ac6c1a169fcd7d
parentf172f0dee931821991905879d03c01a409975983 (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>
-rw-r--r--src/corelib/thread/qthread_unix.cpp25
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()