summaryrefslogtreecommitdiffstats
path: root/src/core/qchangearbiter.cpp
diff options
context:
space:
mode:
authorPaul Lemire <paul.lemire@kdab.com>2014-04-29 11:16:27 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2014-04-30 16:13:35 +0200
commit5d356080f6862956fde632e3caf8600747730e9a (patch)
tree4da35c6e13c6caae5818a7a121d35d8ba452e24b /src/core/qchangearbiter.cpp
parente0ebadcf758e5129f378ec48cee7c2d40b019d6a (diff)
Handle Component property reference changes
A follow up patch with a reworked Entity / Component composition will follow. Change-Id: I7d89fc660f933b43345755529041a9909d1f83a5 Reviewed-by: Sean Harmer <sean.harmer@kdab.com>
Diffstat (limited to 'src/core/qchangearbiter.cpp')
-rw-r--r--src/core/qchangearbiter.cpp22
1 files changed, 12 insertions, 10 deletions
diff --git a/src/core/qchangearbiter.cpp b/src/core/qchangearbiter.cpp
index 3331f6b0d..2df0c863f 100644
--- a/src/core/qchangearbiter.cpp
+++ b/src/core/qchangearbiter.cpp
@@ -83,7 +83,15 @@ void QObservable::notifyObservers(const QSceneChangePtr &e)
QChangeArbiter::QChangeArbiter(QObject *parent)
: QObject(parent)
, m_jobManager(0)
+ , m_mutex(QMutex::Recursive)
{
+ // The QMutex has to be recursive to handle the case where :
+ // 1) SyncChanges is called, mutex is locked
+ // 2) Changes are distributed
+ // 3) An observer decides to register a new observable upon receiving notification
+ // 4) registerObserver locks the mutex once again -> we need recursion otherwise deadlock
+ // 5) Mutex is unlocked - leaving registerObserver
+ // 6) Mutex is unlocked - leaving SyncChanges
}
void QChangeArbiter::initialize(QJobManagerInterface *jobManager)
@@ -152,10 +160,6 @@ void QChangeArbiter::registerObserver(QObserverInterface *observer,
QObserverList &observers = m_observations[subject][changeFlags];
observers.append(observer);
- // TODO: Also store info about types of change observer is interested in so that we
- // can reduce the amount of traffic
- Q_UNUSED(changeFlags);
-
// Register ourselves with the observable as the intermediary
subject->registerObserver(this);
}
@@ -174,10 +178,6 @@ void QChangeArbiter::registerObserver(QObserverInterface *observer,
QObserverList &observers = m_componentObservations[component][changeFlags];
observers.append(observer);
- // TODO: Also store info about types of change observer is interested in so that we
- // can reduce the amount of traffic
- Q_UNUSED(changeFlags);
-
// Register ourselves with the observable as the intermediary
component->registerChangeArbiter(this);
}
@@ -185,6 +185,7 @@ void QChangeArbiter::registerObserver(QObserverInterface *observer,
void QChangeArbiter::unregisterObserver(QObserverInterface *observer,
QObservableInterface *subject)
{
+ QMutexLocker locker(&m_mutex);
if (m_observations.contains(subject)) {
QObserverHash &observers = m_observations[subject];
QList<int> changeFlags = observers.keys();
@@ -196,6 +197,7 @@ void QChangeArbiter::unregisterObserver(QObserverInterface *observer,
void QChangeArbiter::unregisterObserver(QObserverInterface *observer, Component *subject)
{
+ QMutexLocker locker(&m_mutex);
if (m_componentObservations.contains(subject)) {
QObserverHash &observers = m_componentObservations[subject];
QList<int> changeFlags = observers.keys();
@@ -207,13 +209,13 @@ void QChangeArbiter::unregisterObserver(QObserverInterface *observer, Component
void QChangeArbiter::sceneChangeEvent(const QSceneChangePtr &e)
{
- //qDebug() << Q_FUNC_INFO << QThread::currentThread();
+// qDebug() << Q_FUNC_INFO << QThread::currentThread();
// Add the change to the thread local storage queue - no locking required => yay!
ChangeQueue *localChangeQueue = m_tlsChangeQueue.localData();
localChangeQueue->append(e);
- //qDebug() << "Change queue for thread" << QThread::currentThread() << "now contains" << localChangeQueue->count() << "items";
+// qDebug() << "Change queue for thread" << QThread::currentThread() << "now contains" << localChangeQueue->count() << "items";
}
void QChangeArbiter::sceneChangeEventWithLock(const QSceneChangePtr &e)