summaryrefslogtreecommitdiffstats
path: root/src/core/aspects
diff options
context:
space:
mode:
authorSean Harmer <sean.harmer@kdab.com>2016-03-01 12:55:00 +0000
committerSean Harmer <sean.harmer@kdab.com>2016-03-20 11:07:10 +0000
commit64c1c03f406c2a5c0838bff7f7d180ca1acb0408 (patch)
tree7b318a837480c873015cc5daa58f05d4a9310201 /src/core/aspects
parent83b3aecb98a5ef74ba405d3d96b0d586db7baba4 (diff)
Add QAbstractAspectPrivate::onEngineAboutToShutdown() virtual
Gives internal aspects a chance to unqueue any queued work that could potentially deadlock during trying to exit the inner loop in QAspectManager::exec(). Task-number: QTBUG-51421 Change-Id: I8f9892db2d8648c39092720f1a787c4db412d30d Reviewed-by: Paul Lemire <paul.lemire@kdab.com>
Diffstat (limited to 'src/core/aspects')
-rw-r--r--src/core/aspects/qabstractaspect.cpp8
-rw-r--r--src/core/aspects/qabstractaspect_p.h2
-rw-r--r--src/core/aspects/qaspectmanager.cpp12
3 files changed, 22 insertions, 0 deletions
diff --git a/src/core/aspects/qabstractaspect.cpp b/src/core/aspects/qabstractaspect.cpp
index 309fa3faf..20a393738 100644
--- a/src/core/aspects/qabstractaspect.cpp
+++ b/src/core/aspects/qabstractaspect.cpp
@@ -68,6 +68,14 @@ QAbstractAspectPrivate *QAbstractAspectPrivate::get(QAbstractAspect *aspect)
}
/*!
+ *
+ * Called in the context of the main thread
+ */
+void QAbstractAspectPrivate::onEngineAboutToShutdown()
+{
+}
+
+/*!
\class Qt3DCore::QAbstractAspect
\inmodule Qt3DCore
\brief QAbstractAspect is the base class for aspects that provide a vertical slice of behavior.
diff --git a/src/core/aspects/qabstractaspect_p.h b/src/core/aspects/qabstractaspect_p.h
index 5ce480288..5536f1e1d 100644
--- a/src/core/aspects/qabstractaspect_p.h
+++ b/src/core/aspects/qabstractaspect_p.h
@@ -93,6 +93,8 @@ public:
void sceneNodeAdded(Qt3DCore::QSceneChangePtr &e) Q_DECL_OVERRIDE;
void sceneNodeRemoved(Qt3DCore::QSceneChangePtr &e) Q_DECL_OVERRIDE;
+ virtual void onEngineAboutToShutdown();
+
Q_DECLARE_PUBLIC(QAbstractAspect)
QEntity *m_root;
diff --git a/src/core/aspects/qaspectmanager.cpp b/src/core/aspects/qaspectmanager.cpp
index 903d5b219..2f8b0473e 100644
--- a/src/core/aspects/qaspectmanager.cpp
+++ b/src/core/aspects/qaspectmanager.cpp
@@ -99,6 +99,18 @@ void QAspectManager::exitSimulationLoop()
{
qCDebug(Aspects) << Q_FUNC_INFO;
m_runSimulationLoop.fetchAndStoreOrdered(0);
+
+ // Give any aspects a chance to unqueue any asynchronous work they
+ // may have scheduled that would otherwise potentially deadlock or
+ // cause races. For example, the QLogicAspect queues up a vector of
+ // QNodeIds to be processed by a callback on the main thread. However,
+ // if we don't unqueue this work and release its semaphore, the logic
+ // aspect would cause a deadlock when trying to exit the inner loop.
+ // This is because we call this function from the main thread and the
+ // logic aspect is waiting for the main thread to execute the
+ // QLogicComponent::onFrameUpdate() callback.
+ Q_FOREACH (QAbstractAspect *aspect, m_aspects)
+ aspect->d_func()->onEngineAboutToShutdown();
}
bool QAspectManager::isShuttingDown() const