diff options
author | David Faure <david.faure@kdab.com> | 2013-03-18 15:19:44 +0100 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-03-22 16:44:51 +0100 |
commit | f4609b202208fe592d24c7ae3b4a48ee83045497 (patch) | |
tree | c9827efe74688595664c379085ba2a6267e49c13 /src/corelib/kernel/qobject.cpp | |
parent | 85b25fc22176b574865813fa53f7eb2fcbdc89bf (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/kernel/qobject.cpp')
-rw-r--r-- | src/corelib/kernel/qobject.cpp | 20 |
1 files changed, 10 insertions, 10 deletions
diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index 1312e64d8b..583e580762 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -216,8 +216,8 @@ QObjectPrivate::~QObjectPrivate() { if (extraData && !extraData->runningTimers.isEmpty()) { // unregister pending timers - if (threadData->eventDispatcher) - threadData->eventDispatcher->unregisterTimers(q_ptr); + if (threadData->eventDispatcher.load()) + threadData->eventDispatcher.load()->unregisterTimers(q_ptr); // release the timer ids back to the pool for (int i = 0; i < extraData->runningTimers.size(); ++i) @@ -1074,7 +1074,7 @@ bool QObject::event(QEvent *e) case QEvent::ThreadChange: { Q_D(QObject); QThreadData *threadData = d->threadData; - QAbstractEventDispatcher *eventDispatcher = threadData->eventDispatcher; + QAbstractEventDispatcher *eventDispatcher = threadData->eventDispatcher.load(); if (eventDispatcher) { QList<QAbstractEventDispatcher::TimerInfo> timers = eventDispatcher->registeredTimers(this); if (!timers.isEmpty()) { @@ -1354,9 +1354,9 @@ void QObjectPrivate::setThreadData_helper(QThreadData *currentData, QThreadData ++eventsMoved; } } - if (eventsMoved > 0 && targetData->eventDispatcher) { + if (eventsMoved > 0 && targetData->eventDispatcher.load()) { targetData->canWait = false; - targetData->eventDispatcher->wakeUp(); + targetData->eventDispatcher.load()->wakeUp(); } // the current emitting thread shouldn't restore currentSender after calling moveToThread() @@ -1379,7 +1379,7 @@ void QObjectPrivate::_q_reregisterTimers(void *pointer) { Q_Q(QObject); QList<QAbstractEventDispatcher::TimerInfo> *timerList = reinterpret_cast<QList<QAbstractEventDispatcher::TimerInfo> *>(pointer); - QAbstractEventDispatcher *eventDispatcher = threadData->eventDispatcher; + QAbstractEventDispatcher *eventDispatcher = threadData->eventDispatcher.load(); for (int i = 0; i < timerList->size(); ++i) { const QAbstractEventDispatcher::TimerInfo &ti = timerList->at(i); eventDispatcher->registerTimer(ti.timerId, ti.interval, ti.timerType, q); @@ -1438,11 +1438,11 @@ int QObject::startTimer(int interval, Qt::TimerType timerType) return 0; } - if (!d->threadData->eventDispatcher) { + if (!d->threadData->eventDispatcher.load()) { qWarning("QObject::startTimer: QTimer can only be used with threads started with QThread"); return 0; } - int timerId = d->threadData->eventDispatcher->registerTimer(interval, timerType, this); + int timerId = d->threadData->eventDispatcher.load()->registerTimer(interval, timerType, this); if (!d->extraData) d->extraData = new QObjectPrivate::ExtraData; d->extraData->runningTimers.append(timerId); @@ -1472,8 +1472,8 @@ void QObject::killTimer(int id) return; } - if (d->threadData->eventDispatcher) - d->threadData->eventDispatcher->unregisterTimer(id); + if (d->threadData->eventDispatcher.load()) + d->threadData->eventDispatcher.load()->unregisterTimer(id); d->extraData->runningTimers.remove(at); QAbstractEventDispatcherPrivate::releaseTimerId(id); |