diff options
author | Sean Harmer <sean.harmer@kdab.com> | 2016-05-16 18:55:56 +0100 |
---|---|---|
committer | Sean Harmer <sean.harmer@kdab.com> | 2016-05-20 18:18:15 +0000 |
commit | b6abf3d5104dc573f6df049580f77d278a7c30d0 (patch) | |
tree | 918e50c206d7bb0ef543317eb9a32dbe0edffd39 /src/core/aspects/qaspectmanager.cpp | |
parent | 701764ed4835d6ca9fd7c06f0ae824bea9bfde51 (diff) |
Allow the backend chance to process any final changes during shutdown
The QAspectEngine now flushes any pending changes batched up before
telling the aspect manager to exit the simulation loop.
Furthermore, the call to QAspectManager::exitSimulationLoop() now
waits until the aspect thread has completely finished the simulation
loop and has called onEngineShutdown() on each of the aspects. This is
important to ensure that the main thread doesn't call
QAspectEngine::shutdown() too early as this deletes the change queue
which contains the final changes sent from the main thread during
shutdown.
For some reason the backend is unable to find which
QBackendNodeMapper corresponds to each destruction change. Will
investigate that next.
Task-number: QTBUG-42353
Change-Id: Iec4d6a57a163effefd5b60249bf97c76ed187413
Reviewed-by: Kevin Ottens <kevin.ottens@kdab.com>
Diffstat (limited to 'src/core/aspects/qaspectmanager.cpp')
-rw-r--r-- | src/core/aspects/qaspectmanager.cpp | 11 |
1 files changed, 11 insertions, 0 deletions
diff --git a/src/core/aspects/qaspectmanager.cpp b/src/core/aspects/qaspectmanager.cpp index d565848a8..993b86e08 100644 --- a/src/core/aspects/qaspectmanager.cpp +++ b/src/core/aspects/qaspectmanager.cpp @@ -73,6 +73,7 @@ QAspectManager::QAspectManager(QObject *parent) , m_jobManager(new QAspectJobManager(this)) , m_changeArbiter(new QChangeArbiter(this)) , m_serviceLocator(new QServiceLocator()) + , m_waitForEndOfSimulationLoop(0) , m_waitForEndOfExecLoop(0) , m_waitForQuit(0) { @@ -115,6 +116,10 @@ void QAspectManager::exitSimulationLoop() // QLogicComponent::onFrameUpdate() callback. for (QAbstractAspect *aspect : qAsConst(m_aspects)) aspect->d_func()->onEngineAboutToShutdown(); + + // Wait until the simulation loop is fully exited and the aspects are done + // processing any final changes and have had onEngineShutdown() called on them + m_waitForEndOfSimulationLoop.acquire(1); } bool QAspectManager::isShuttingDown() const @@ -278,6 +283,9 @@ void QAspectManager::exec() } // End of simulation loop if (needsShutdown) { + // Process any pending changes from the frontend before we shut the aspects down + m_changeArbiter->syncChanges(); + // Give aspects a chance to perform any shutdown actions. This may include unqueuing // any blocking work on the main thread that could potentially deadlock during shutdown. qCDebug(Aspects) << "Calling onEngineShutdown() for each aspect"; @@ -286,6 +294,9 @@ void QAspectManager::exec() aspect->onEngineShutdown(); } qCDebug(Aspects) << "Done calling onEngineShutdown() for each aspect"; + + // Wake up the main thread which is waiting for us inside of exitSimulationLoop() + m_waitForEndOfSimulationLoop.release(1); } } // End of main loop qCDebug(Aspects) << Q_FUNC_INFO << "***** Exited main loop *****"; |