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>
This commit is contained in:
parent
f172f0dee9
commit
90f1ef14aa
@ -116,18 +116,11 @@ static pthread_key_t current_thread_data_key;
|
|||||||
|
|
||||||
static void destroy_current_thread_data(void *p)
|
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);
|
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) {
|
if (data->isAdopted) {
|
||||||
QThread *thread = data->thread.loadAcquire();
|
QThread *thread = data->thread.loadAcquire();
|
||||||
Q_ASSERT(thread);
|
Q_ASSERT(thread);
|
||||||
@ -138,14 +131,8 @@ static void destroy_current_thread_data(void *p)
|
|||||||
data->deref();
|
data->deref();
|
||||||
|
|
||||||
// ... but we must reset it to zero before returning so we aren't
|
// ... but we must reset it to zero before returning so we aren't
|
||||||
// called again (POSIX allows implementations to call destructor
|
// leaving a dangling pointer.
|
||||||
// functions repeatedly until all values are zero)
|
currentThreadData = nullptr;
|
||||||
pthread_setspecific(current_thread_data_key,
|
|
||||||
#if defined(Q_OS_VXWORKS)
|
|
||||||
(void *)1);
|
|
||||||
#else
|
|
||||||
nullptr);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void create_current_thread_data_key()
|
static void create_current_thread_data_key()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user