diff options
author | Volker Hilsheimer <volker.hilsheimer@qt.io> | 2022-01-10 18:10:48 +0100 |
---|---|---|
committer | Volker Hilsheimer <volker.hilsheimer@qt.io> | 2022-01-12 12:44:38 +0100 |
commit | 4a4240f1bdf184a52a22b94f37090b07434770e7 (patch) | |
tree | 936b84e3fefd72e4f97be10877326d710f80dedf /src/corelib/thread | |
parent | e9fd1c6aab28f027760da76ebc154f0ff9aefcf8 (diff) |
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>
Diffstat (limited to 'src/corelib/thread')
-rw-r--r-- | src/corelib/thread/qthread_p.h | 7 | ||||
-rw-r--r-- | src/corelib/thread/qthread_unix.cpp | 7 | ||||
-rw-r--r-- | src/corelib/thread/qthread_win.cpp | 8 |
3 files changed, 16 insertions, 6 deletions
diff --git a/src/corelib/thread/qthread_p.h b/src/corelib/thread/qthread_p.h index 0a3813ab3b..aa6183f7e2 100644 --- a/src/corelib/thread/qthread_p.h +++ b/src/corelib/thread/qthread_p.h @@ -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) diff --git a/src/corelib/thread/qthread_unix.cpp b/src/corelib/thread/qthread_unix.cpp index 53395d9a95..32cada5e9d 100644 --- a/src/corelib/thread/qthread_unix.cpp +++ b/src/corelib/thread/qthread_unix.cpp @@ -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) { diff --git a/src/corelib/thread/qthread_win.cpp b/src/corelib/thread/qthread_win.cpp index 4b144ebda4..6249b94ea2 100644 --- a/src/corelib/thread/qthread_win.cpp +++ b/src/corelib/thread/qthread_win.cpp @@ -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; |