summaryrefslogtreecommitdiffstats
path: root/src/corelib/thread
diff options
context:
space:
mode:
authorDavid Faure <david.faure@kdab.com>2015-08-01 15:50:00 +0200
committerDavid Faure <david.faure@kdab.com>2015-09-22 07:55:03 +0000
commitec6556a2b99df373eb43ca009340a7f0f19bacbd (patch)
tree8bdcbf73f4d66a7d86d6c6afdfa93708b9ec34f7 /src/corelib/thread
parent71df75966db5f51c66bff1c436dd1cb5a895b51b (diff)
Fix two data races in QThread/QThreadData
* theMainThread is written by the main thread and read by QThreadData::~QThreadData() (any managed thread) * QThreadData::thread is written by QThread::~QThread (in the parent thread) and read+written by QThreadData::~QThreadData (in the managed thread). This can happen because QThreadData is refcounted so the managed thread (which derefs it) races with the parent thread (which sets it to 0). Change-Id: I72de793716391a0937254cda6b4328fcad5060c7 Reviewed-by: Olivier Goffart (Woboq GmbH) <ogoffart@woboq.com>
Diffstat (limited to 'src/corelib/thread')
-rw-r--r--src/corelib/thread/qthread_p.h2
-rw-r--r--src/corelib/thread/qthread_unix.cpp2
-rw-r--r--src/corelib/thread/qthread_win.cpp2
-rw-r--r--src/corelib/thread/qthreadstorage.cpp6
4 files changed, 6 insertions, 6 deletions
diff --git a/src/corelib/thread/qthread_p.h b/src/corelib/thread/qthread_p.h
index 1ecd682ad1..8331816729 100644
--- a/src/corelib/thread/qthread_p.h
+++ b/src/corelib/thread/qthread_p.h
@@ -269,7 +269,7 @@ public:
QStack<QEventLoop *> eventLoops;
QPostEventList postEventList;
- QThread *thread;
+ QAtomicPointer<QThread> thread;
Qt::HANDLE threadId;
QAtomicPointer<QAbstractEventDispatcher> eventDispatcher;
QVector<void *> tls;
diff --git a/src/corelib/thread/qthread_unix.cpp b/src/corelib/thread/qthread_unix.cpp
index 77093c9cf1..5698a61326 100644
--- a/src/corelib/thread/qthread_unix.cpp
+++ b/src/corelib/thread/qthread_unix.cpp
@@ -225,7 +225,7 @@ QThreadData *QThreadData::current(bool createIfNecessary)
data->isAdopted = true;
data->threadId = (Qt::HANDLE)pthread_self();
if (!QCoreApplicationPrivate::theMainThread)
- QCoreApplicationPrivate::theMainThread = data->thread;
+ QCoreApplicationPrivate::theMainThread = data->thread.load();
}
return data;
}
diff --git a/src/corelib/thread/qthread_win.cpp b/src/corelib/thread/qthread_win.cpp
index c16a2e958c..a4b853d62e 100644
--- a/src/corelib/thread/qthread_win.cpp
+++ b/src/corelib/thread/qthread_win.cpp
@@ -121,7 +121,7 @@ QThreadData *QThreadData::current(bool createIfNecessary)
threadData->threadId = reinterpret_cast<Qt::HANDLE>(GetCurrentThreadId());
if (!QCoreApplicationPrivate::theMainThread) {
- QCoreApplicationPrivate::theMainThread = threadData->thread;
+ QCoreApplicationPrivate::theMainThread = threadData->thread.load();
// TODO: is there a way to reflect the branch's behavior using
// WinRT API?
} else {
diff --git a/src/corelib/thread/qthreadstorage.cpp b/src/corelib/thread/qthreadstorage.cpp
index 05ab01cc54..37892233f3 100644
--- a/src/corelib/thread/qthreadstorage.cpp
+++ b/src/corelib/thread/qthreadstorage.cpp
@@ -121,7 +121,7 @@ void **QThreadStorageData::get() const
DEBUG_MSG("QThreadStorageData: Returning storage %d, data %p, for thread %p",
id,
*v,
- data->thread);
+ data->thread.load());
return *v ? v : 0;
}
@@ -143,7 +143,7 @@ void **QThreadStorageData::set(void *p)
DEBUG_MSG("QThreadStorageData: Deleting previous storage %d, data %p, for thread %p",
id,
value,
- data->thread);
+ data->thread.load());
QMutexLocker locker(&destructorsMutex);
DestructorMap *destr = destructors();
@@ -159,7 +159,7 @@ void **QThreadStorageData::set(void *p)
// store new data
value = p;
- DEBUG_MSG("QThreadStorageData: Set storage %d for thread %p to %p", id, data->thread, p);
+ DEBUG_MSG("QThreadStorageData: Set storage %d for thread %p to %p", id, data->thread.load(), p);
return &value;
}