summaryrefslogtreecommitdiffstats
path: root/src/corelib/thread
diff options
context:
space:
mode:
authorVolker Hilsheimer <volker.hilsheimer@qt.io>2022-01-10 18:10:48 +0100
committerVolker Hilsheimer <volker.hilsheimer@qt.io>2022-01-12 12:44:38 +0100
commit4a4240f1bdf184a52a22b94f37090b07434770e7 (patch)
tree936b84e3fefd72e4f97be10877326d710f80dedf /src/corelib/thread
parente9fd1c6aab28f027760da76ebc154f0ff9aefcf8 (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.h7
-rw-r--r--src/corelib/thread/qthread_unix.cpp7
-rw-r--r--src/corelib/thread/qthread_win.cpp8
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;