diff options
author | Sean Harmer <sean.harmer@kdab.com> | 2016-03-01 12:55:00 +0000 |
---|---|---|
committer | Sean Harmer <sean.harmer@kdab.com> | 2016-03-20 11:07:10 +0000 |
commit | 64c1c03f406c2a5c0838bff7f7d180ca1acb0408 (patch) | |
tree | 7b318a837480c873015cc5daa58f05d4a9310201 /src/core/aspects | |
parent | 83b3aecb98a5ef74ba405d3d96b0d586db7baba4 (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.cpp | 8 | ||||
-rw-r--r-- | src/core/aspects/qabstractaspect_p.h | 2 | ||||
-rw-r--r-- | src/core/aspects/qaspectmanager.cpp | 12 |
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 |