Turn QThreadData::threadId into a QAtomicPointer
Solves a data race found by TSan. Since thread and threadId are QAtomicPointer, I've removed the explicit initialization in the QThreadData constructor Task-number: QTBUG-58855 Change-Id: I4139d5f93dcb4b429ae9fffd14a34082f2683f76 Reviewed-by: Marc Mutz <marc.mutz@kdab.com>
This commit is contained in:
parent
265db5ad9b
commit
b58af67d7b
@ -3686,7 +3686,7 @@ void QMetaObject::activate(QObject *sender, int signalOffset, int local_signal_i
|
||||
continue;
|
||||
|
||||
QObject * const receiver = c->receiver;
|
||||
const bool receiverInSameThread = currentThreadId == receiver->d_func()->threadData->threadId;
|
||||
const bool receiverInSameThread = currentThreadId == receiver->d_func()->threadData->threadId.load();
|
||||
|
||||
// determine if this connection should be sent immediately or
|
||||
// put into the event queue
|
||||
|
@ -56,7 +56,7 @@ QT_BEGIN_NAMESPACE
|
||||
*/
|
||||
|
||||
QThreadData::QThreadData(int initialRefCount)
|
||||
: _ref(initialRefCount), loopLevel(0), scopeLevel(0), thread(0), threadId(0),
|
||||
: _ref(initialRefCount), loopLevel(0), scopeLevel(0),
|
||||
eventDispatcher(0),
|
||||
quitNow(false), canWait(true), isAdopted(false), requiresCoreApplication(true)
|
||||
{
|
||||
|
@ -284,7 +284,7 @@ public:
|
||||
QStack<QEventLoop *> eventLoops;
|
||||
QPostEventList postEventList;
|
||||
QAtomicPointer<QThread> thread;
|
||||
Qt::HANDLE threadId;
|
||||
QAtomicPointer<void> threadId;
|
||||
QAtomicPointer<QAbstractEventDispatcher> eventDispatcher;
|
||||
QVector<void *> tls;
|
||||
FlaggedDebugSignatures flaggedSignatures;
|
||||
|
@ -255,7 +255,7 @@ QThreadData *QThreadData::current(bool createIfNecessary)
|
||||
}
|
||||
data->deref();
|
||||
data->isAdopted = true;
|
||||
data->threadId = to_HANDLE(pthread_self());
|
||||
data->threadId.store(to_HANDLE(pthread_self()));
|
||||
if (!QCoreApplicationPrivate::theMainThread)
|
||||
QCoreApplicationPrivate::theMainThread = data->thread.load();
|
||||
}
|
||||
@ -335,7 +335,7 @@ void *QThreadPrivate::start(void *arg)
|
||||
thr->d_func()->setPriority(QThread::Priority(thr->d_func()->priority & ~ThreadPriorityResetFlag));
|
||||
}
|
||||
|
||||
data->threadId = to_HANDLE(pthread_self());
|
||||
data->threadId.store(to_HANDLE(pthread_self()));
|
||||
set_thread_data(data);
|
||||
|
||||
data->ref();
|
||||
@ -352,7 +352,7 @@ void *QThreadPrivate::start(void *arg)
|
||||
// sets the name of the current thread.
|
||||
QString objectName = thr->objectName();
|
||||
|
||||
pthread_t thread_id = from_HANDLE<pthread_t>(data->threadId);
|
||||
pthread_t thread_id = from_HANDLE<pthread_t>(data->threadId.load());
|
||||
if (Q_LIKELY(objectName.isEmpty()))
|
||||
setCurrentThreadName(thread_id, thr->metaObject()->className());
|
||||
else
|
||||
@ -651,7 +651,7 @@ void QThread::start(Priority priority)
|
||||
#endif
|
||||
code = pthread_create(&threadId, &attr, QThreadPrivate::start, this);
|
||||
}
|
||||
d->data->threadId = to_HANDLE(threadId);
|
||||
d->data->threadId.store(to_HANDLE(threadId));
|
||||
|
||||
pthread_attr_destroy(&attr);
|
||||
|
||||
@ -660,7 +660,7 @@ void QThread::start(Priority priority)
|
||||
|
||||
d->running = false;
|
||||
d->finished = false;
|
||||
d->data->threadId = 0;
|
||||
d->data->threadId.store(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
@ -670,10 +670,10 @@ void QThread::terminate()
|
||||
Q_D(QThread);
|
||||
QMutexLocker locker(&d->mutex);
|
||||
|
||||
if (!d->data->threadId)
|
||||
if (!d->data->threadId.load())
|
||||
return;
|
||||
|
||||
int code = pthread_cancel(from_HANDLE<pthread_t>(d->data->threadId));
|
||||
int code = pthread_cancel(from_HANDLE<pthread_t>(d->data->threadId.load()));
|
||||
if (code) {
|
||||
qWarning("QThread::start: Thread termination error: %s",
|
||||
qPrintable(qt_error_string((code))));
|
||||
@ -686,7 +686,7 @@ bool QThread::wait(unsigned long time)
|
||||
Q_D(QThread);
|
||||
QMutexLocker locker(&d->mutex);
|
||||
|
||||
if (from_HANDLE<pthread_t>(d->data->threadId) == pthread_self()) {
|
||||
if (from_HANDLE<pthread_t>(d->data->threadId.load()) == pthread_self()) {
|
||||
qWarning("QThread::wait: Thread tried to wait on itself");
|
||||
return false;
|
||||
}
|
||||
@ -728,7 +728,7 @@ void QThreadPrivate::setPriority(QThread::Priority threadPriority)
|
||||
int sched_policy;
|
||||
sched_param param;
|
||||
|
||||
if (pthread_getschedparam(from_HANDLE<pthread_t>(data->threadId), &sched_policy, ¶m) != 0) {
|
||||
if (pthread_getschedparam(from_HANDLE<pthread_t>(data->threadId.load()), &sched_policy, ¶m) != 0) {
|
||||
// failed to get the scheduling policy, don't bother setting
|
||||
// the priority
|
||||
qWarning("QThread::setPriority: Cannot get scheduler parameters");
|
||||
@ -744,15 +744,15 @@ void QThreadPrivate::setPriority(QThread::Priority threadPriority)
|
||||
}
|
||||
|
||||
param.sched_priority = prio;
|
||||
int status = pthread_setschedparam(from_HANDLE<pthread_t>(data->threadId), sched_policy, ¶m);
|
||||
int status = pthread_setschedparam(from_HANDLE<pthread_t>(data->threadId.load()), sched_policy, ¶m);
|
||||
|
||||
# ifdef SCHED_IDLE
|
||||
// were we trying to set to idle priority and failed?
|
||||
if (status == -1 && sched_policy == SCHED_IDLE && errno == EINVAL) {
|
||||
// reset to lowest priority possible
|
||||
pthread_getschedparam(from_HANDLE<pthread_t>(data->threadId), &sched_policy, ¶m);
|
||||
pthread_getschedparam(from_HANDLE<pthread_t>(data->threadId.load()), &sched_policy, ¶m);
|
||||
param.sched_priority = sched_get_priority_min(sched_policy);
|
||||
pthread_setschedparam(from_HANDLE<pthread_t>(data->threadId), sched_policy, ¶m);
|
||||
pthread_setschedparam(from_HANDLE<pthread_t>(data->threadId.load()), sched_policy, ¶m);
|
||||
}
|
||||
# else
|
||||
Q_UNUSED(status);
|
||||
|
@ -137,7 +137,7 @@ QThreadData *QThreadData::current(bool createIfNecessary)
|
||||
}
|
||||
threadData->deref();
|
||||
threadData->isAdopted = true;
|
||||
threadData->threadId = reinterpret_cast<Qt::HANDLE>(quintptr(GetCurrentThreadId()));
|
||||
threadData->threadId.store(reinterpret_cast<Qt::HANDLE>(quintptr(GetCurrentThreadId())));
|
||||
|
||||
if (!QCoreApplicationPrivate::theMainThread) {
|
||||
QCoreApplicationPrivate::theMainThread = threadData->thread.load();
|
||||
@ -351,7 +351,7 @@ unsigned int __stdcall QT_ENSURE_STACK_ALIGNED_FOR_SSE QThreadPrivate::start(voi
|
||||
|
||||
qt_create_tls();
|
||||
TlsSetValue(qt_current_thread_data_tls_index, data);
|
||||
data->threadId = reinterpret_cast<Qt::HANDLE>(quintptr(GetCurrentThreadId()));
|
||||
data->threadId.store(reinterpret_cast<Qt::HANDLE>(quintptr(GetCurrentThreadId())));
|
||||
|
||||
QThread::setTerminationEnabled(false);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user