Don't access QObject::objectName during QThread start
This is a data race, as the thread accesses QObject::objectName on the QThread instance while the thread owning the QThread might modify the objectName. Instead, make a copy in the QThreadPrivate that can be accessed safely. Task-number: QTBUG-96718 Pick-to: 6.3 6.2 5.15 Change-Id: I10701551d498993ca5055daf161636bfb648840c Reviewed-by: Marc Mutz <marc.mutz@qt.io>bb10
parent
e9fd1c6aab
commit
4a4240f1bd
|
|
@ -201,6 +201,13 @@ public:
|
|||
QCoreApplication::instance()->postEvent(q_ptr, new QEvent(QEvent::Quit));
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef Q_OS_INTEGRITY
|
||||
private:
|
||||
// Used in QThread(Private)::start to avoid racy access to QObject::objectName,
|
||||
// unset afterwards. On INTEGRITY we set the thread name before starting it.
|
||||
QString objectName;
|
||||
#endif
|
||||
};
|
||||
|
||||
#else // QT_CONFIG(thread)
|
||||
|
|
|
|||
|
|
@ -343,10 +343,10 @@ void *QThreadPrivate::start(void *arg)
|
|||
// Sets the name of the current thread. We can only do this
|
||||
// when the thread is starting, as we don't have a cross
|
||||
// platform way of setting the name of an arbitrary thread.
|
||||
if (Q_LIKELY(thr->objectName().isEmpty()))
|
||||
if (Q_LIKELY(thr->d_func()->objectName.isEmpty()))
|
||||
setCurrentThreadName(thr->metaObject()->className());
|
||||
else
|
||||
setCurrentThreadName(thr->objectName().toLocal8Bit());
|
||||
setCurrentThreadName(std::exchange(thr->d_func()->objectName, {}).toLocal8Bit());
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -734,7 +734,10 @@ void QThread::start(Priority priority)
|
|||
pthread_attr_setthreadname(&attr, metaObject()->className());
|
||||
else
|
||||
pthread_attr_setthreadname(&attr, objectName().toLocal8Bit());
|
||||
#else
|
||||
d->objectName = objectName();
|
||||
#endif
|
||||
|
||||
pthread_t threadId;
|
||||
int code = pthread_create(&threadId, &attr, QThreadPrivate::start, this);
|
||||
if (code == EPERM) {
|
||||
|
|
|
|||
|
|
@ -316,10 +316,9 @@ unsigned int __stdcall QT_ENSURE_STACK_ALIGNED_FOR_SSE QThreadPrivate::start(voi
|
|||
|
||||
#if !defined(QT_NO_DEBUG) && defined(Q_CC_MSVC)
|
||||
// sets the name of the current thread.
|
||||
QByteArray objectName = thr->objectName().toLocal8Bit();
|
||||
qt_set_thread_name(HANDLE(-1),
|
||||
objectName.isEmpty() ?
|
||||
thr->metaObject()->className() : objectName.constData());
|
||||
qt_set_thread_name(HANDLE(-1), thr->d_func()->objectName.isEmpty()
|
||||
? thr->metaObject()->className()
|
||||
: std::exchange(thr->d_func()->objectName, {}).toLocal8Bit().constData());
|
||||
#endif
|
||||
|
||||
emit thr->started(QThread::QPrivateSignal());
|
||||
|
|
@ -421,6 +420,7 @@ void QThread::start(Priority priority)
|
|||
if (d->running)
|
||||
return;
|
||||
|
||||
d->objectName = objectName();
|
||||
d->running = true;
|
||||
d->finished = false;
|
||||
d->exited = false;
|
||||
|
|
|
|||
Loading…
Reference in New Issue