summaryrefslogtreecommitdiffstats
path: root/src/corelib/thread
diff options
context:
space:
mode:
authorDavid Faure <david.faure@kdab.com>2013-03-18 15:19:44 +0100
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-03-22 16:44:51 +0100
commitf4609b202208fe592d24c7ae3b4a48ee83045497 (patch)
treec9827efe74688595664c379085ba2a6267e49c13 /src/corelib/thread
parent85b25fc22176b574865813fa53f7eb2fcbdc89bf (diff)
QThread: fix race when setting the eventDispatcher
Use QAtomicPointer to make this thread-safe. Change-Id: If71f204699fcefabdb59bd26342d777d1cc9e2a7 Reviewed-by: Olivier Goffart <ogoffart@woboq.com>
Diffstat (limited to 'src/corelib/thread')
-rw-r--r--src/corelib/thread/qthread.cpp4
-rw-r--r--src/corelib/thread/qthread_p.h4
-rw-r--r--src/corelib/thread/qthread_unix.cpp14
-rw-r--r--src/corelib/thread/qthread_win.cpp11
4 files changed, 18 insertions, 15 deletions
diff --git a/src/corelib/thread/qthread.cpp b/src/corelib/thread/qthread.cpp
index dd4d4e74ae..d230c8a145 100644
--- a/src/corelib/thread/qthread.cpp
+++ b/src/corelib/thread/qthread.cpp
@@ -752,7 +752,7 @@ QThread::QThread(QThreadPrivate &dd, QObject *parent)
QAbstractEventDispatcher *QThread::eventDispatcher() const
{
Q_D(const QThread);
- return d->data->eventDispatcher;
+ return d->data->eventDispatcher.load();
}
/*!
@@ -767,7 +767,7 @@ QAbstractEventDispatcher *QThread::eventDispatcher() const
void QThread::setEventDispatcher(QAbstractEventDispatcher *eventDispatcher)
{
Q_D(QThread);
- if (d->data->eventDispatcher != 0) {
+ if (d->data->hasEventDispatcher()) {
qWarning("QThread::setEventDispatcher: An event dispatcher has already been created for this thread");
} else {
eventDispatcher->moveToThread(this);
diff --git a/src/corelib/thread/qthread_p.h b/src/corelib/thread/qthread_p.h
index 8e9eb1035a..7e963fdcd1 100644
--- a/src/corelib/thread/qthread_p.h
+++ b/src/corelib/thread/qthread_p.h
@@ -230,6 +230,8 @@ public:
void ref();
void deref();
+ inline bool hasEventDispatcher() const
+ { return eventDispatcher.load() != 0; }
bool canWaitLocked()
{
@@ -241,7 +243,7 @@ public:
Qt::HANDLE threadId;
bool quitNow;
int loopLevel;
- QAbstractEventDispatcher *eventDispatcher;
+ QAtomicPointer<QAbstractEventDispatcher> eventDispatcher;
QStack<QEventLoop *> eventLoops;
QPostEventList postEventList;
bool canWait;
diff --git a/src/corelib/thread/qthread_unix.cpp b/src/corelib/thread/qthread_unix.cpp
index 44ad8d3ac2..b7e94366fe 100644
--- a/src/corelib/thread/qthread_unix.cpp
+++ b/src/corelib/thread/qthread_unix.cpp
@@ -258,19 +258,19 @@ typedef void*(*QtThreadCallback)(void*);
void QThreadPrivate::createEventDispatcher(QThreadData *data)
{
#if defined(Q_OS_BLACKBERRY)
- data->eventDispatcher = new QEventDispatcherBlackberry;
+ data->eventDispatcher.storeRelease(new QEventDispatcherBlackberry);
#else
#if !defined(QT_NO_GLIB)
if (qEnvironmentVariableIsEmpty("QT_NO_GLIB")
&& qEnvironmentVariableIsEmpty("QT_NO_THREADED_GLIB")
&& QEventDispatcherGlib::versionSupported())
- data->eventDispatcher = new QEventDispatcherGlib;
+ data->eventDispatcher.storeRelease(new QEventDispatcherGlib);
else
#endif
- data->eventDispatcher = new QEventDispatcherUNIX;
+ data->eventDispatcher.storeRelease(new QEventDispatcherUNIX);
#endif
- data->eventDispatcher->startingUp();
+ data->eventDispatcher.load()->startingUp();
}
#ifndef QT_NO_THREAD
@@ -314,8 +314,8 @@ void *QThreadPrivate::start(void *arg)
data->quitNow = thr->d_func()->exited;
}
- if (data->eventDispatcher) // custom event dispatcher set?
- data->eventDispatcher->startingUp();
+ if (data->eventDispatcher.load()) // custom event dispatcher set?
+ data->eventDispatcher.load()->startingUp();
else
createEventDispatcher(data);
@@ -358,7 +358,7 @@ void QThreadPrivate::finish(void *arg)
QThreadStorageData::finish((void **)data);
locker.relock();
- QAbstractEventDispatcher *eventDispatcher = d->data->eventDispatcher;
+ QAbstractEventDispatcher *eventDispatcher = d->data->eventDispatcher.load();
if (eventDispatcher) {
d->data->eventDispatcher = 0;
locker.unlock();
diff --git a/src/corelib/thread/qthread_win.cpp b/src/corelib/thread/qthread_win.cpp
index 0cf903bb3a..ddf499f3bb 100644
--- a/src/corelib/thread/qthread_win.cpp
+++ b/src/corelib/thread/qthread_win.cpp
@@ -306,8 +306,9 @@ void qt_set_thread_name(HANDLE threadId, LPCSTR threadName)
void QThreadPrivate::createEventDispatcher(QThreadData *data)
{
- data->eventDispatcher = new QEventDispatcherWin32;
- data->eventDispatcher->startingUp();
+ QEventDispatcherWin32 *theEventDispatcher = new QEventDispatcherWin32;
+ data->eventDispatcher.storeRelease(theEventDispatcher);
+ theEventDispatcher->startingUp();
}
#ifndef QT_NO_THREAD
@@ -328,8 +329,8 @@ unsigned int __stdcall QT_ENSURE_STACK_ALIGNED_FOR_SSE QThreadPrivate::start(voi
data->quitNow = thr->d_func()->exited;
}
- if (data->eventDispatcher) // custom event dispatcher set?
- data->eventDispatcher->startingUp();
+ if (data->eventDispatcher.load()) // custom event dispatcher set?
+ data->eventDispatcher.load()->startingUp();
else
createEventDispatcher(data);
@@ -364,7 +365,7 @@ void QThreadPrivate::finish(void *arg, bool lockAnyway)
QThreadStorageData::finish(tls_data);
locker.relock();
- QAbstractEventDispatcher *eventDispatcher = d->data->eventDispatcher;
+ QAbstractEventDispatcher *eventDispatcher = d->data->eventDispatcher.load();
if (eventDispatcher) {
d->data->eventDispatcher = 0;
locker.unlock();