Don't rely on TLS to call QThread::finish on VxW
On VxWorks, its pthread implementation fails on call to `pthead_setspecific` which is made by first `QObject` constructor during `QThreadPrivate::finish()`. This causes call to `QThreadData::current`, since `QObject` doesn't have parent, and since the pthread is already removed, it tries to set `QThreadData` for current pthread key, which crashes. The aforementioned `QObject`'s instances are created in multiple places during `QThreadPrivate::finish` method, first one in during call to `qCDebug()`. The sequence currently leading to call to `QThreadData::current` starts with `qCDebug` call in `QThreadPrivate::finish`, which: - creates `QDebug` object, which - creates `Stream`, which - creates `QTextStream`, which - creates `QTextStreamPrivate`, which - creates `QDeviceClosedNotifier`, which - is a `QObject`, which - calls `QThreadData::current()` because its `parent` is nullptr. Even ignoring debug print, next line calls `QCoreApplication::sendPostedEvents` which calls `QThreadData::current` directly. Pick-to: 6.7 Task-number: QTBUG-115777 Change-Id: I4d405eebdff0c63c6cd66fba4eaa95c3818ceaea Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
parent
0beaa63d4a
commit
e82b79d382
@ -282,9 +282,13 @@ void *QThreadPrivate::start(void *arg)
|
|||||||
#ifdef PTHREAD_CANCEL_DISABLE
|
#ifdef PTHREAD_CANCEL_DISABLE
|
||||||
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, nullptr);
|
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, nullptr);
|
||||||
#endif
|
#endif
|
||||||
#if !defined(Q_OS_QNX)
|
#if !defined(Q_OS_QNX) && !defined(Q_OS_VXWORKS)
|
||||||
// On QNX, calling finish() from a thread_local destructor causes the C
|
// On QNX, calling finish() from a thread_local destructor causes the C
|
||||||
// library to hang.
|
// library to hang.
|
||||||
|
// On VxWorks, its pthread implementation fails on call to `pthead_setspecific` which is made
|
||||||
|
// by first QObject constructor during `finish()`. This causes call to QThread::current, since
|
||||||
|
// QObject doesn't have parent, and since the pthread is already removed, it tries to set
|
||||||
|
// QThreadData for current pthread key, which crashes.
|
||||||
static thread_local
|
static thread_local
|
||||||
#endif
|
#endif
|
||||||
auto cleanup = qScopeGuard([=] { finish(arg); });
|
auto cleanup = qScopeGuard([=] { finish(arg); });
|
||||||
|
Loading…
x
Reference in New Issue
Block a user