From 03b73243252fbbf3ba7ae3831a45b96397ecc935 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Wed, 26 May 2021 09:06:06 +0200 Subject: [PATCH] CppProjectUpdater: Wait for all tasks to be finished in d'tor It may happen that the old task was canceled and still running while the new task was started. Later, when the d'tor is called both old and new tasks may still be running. Before we waited only for the new task to be finished in d'tor. Now we are waiting for all tasks to be finished. Amends: 7fb592fe0cfec22ae7e966b9c6b88aa801bf9592 Task-number: QTCREATORBUG-25709 Change-Id: Id4b44cd36ee03aa45472b15d8fbb25a2cab77e92 Reviewed-by: Christian Kandeler --- src/plugins/cpptools/cppprojectupdater.cpp | 26 ++++++---------------- src/plugins/cpptools/cppprojectupdater.h | 8 +++---- 2 files changed, 10 insertions(+), 24 deletions(-) diff --git a/src/plugins/cpptools/cppprojectupdater.cpp b/src/plugins/cpptools/cppprojectupdater.cpp index 567aabde5ee..794fd7abe7f 100644 --- a/src/plugins/cpptools/cppprojectupdater.cpp +++ b/src/plugins/cpptools/cppprojectupdater.cpp @@ -43,11 +43,7 @@ CppProjectUpdater::CppProjectUpdater() &QFutureWatcher::finished, this, &CppProjectUpdater::onProjectInfoGenerated); -} - -CppProjectUpdater::~CppProjectUpdater() -{ - cancelAndWaitForFinished(); + m_futureSynchronizer.setCancelOnWait(true); } void CppProjectUpdater::update(const ProjectExplorer::ProjectUpdateInfo &projectUpdateInfo) @@ -63,30 +59,21 @@ void CppProjectUpdater::update(const ProjectExplorer::ProjectUpdateInfo &project this, &CppProjectUpdater::onToolChainRemoved); // Run the project info generator in a worker thread and continue if that one is finished. - m_generateFuture = Utils::runAsync([=](QFutureInterface &futureInterface) { + auto generateFuture = Utils::runAsync([=](QFutureInterface &futureInterface) { ProjectUpdateInfo fullProjectUpdateInfo = projectUpdateInfo; if (fullProjectUpdateInfo.rppGenerator) fullProjectUpdateInfo.rawProjectParts = fullProjectUpdateInfo.rppGenerator(); Internal::ProjectInfoGenerator generator(futureInterface, fullProjectUpdateInfo); futureInterface.reportResult(generator.generate()); }); - m_generateFutureWatcher.setFuture(m_generateFuture); + m_generateFutureWatcher.setFuture(generateFuture); + m_futureSynchronizer.addFuture(generateFuture); } void CppProjectUpdater::cancel() { m_generateFutureWatcher.setFuture({}); - m_generateFuture.cancel(); - m_updateFuture.cancel(); -} - -void CppProjectUpdater::cancelAndWaitForFinished() -{ - cancel(); - if (m_generateFuture.isRunning()) - m_generateFuture.waitForFinished(); - if (m_updateFuture.isRunning()) - m_updateFuture.waitForFinished(); + m_futureSynchronizer.cancelAllFutures(); } void CppProjectUpdater::onToolChainRemoved(ProjectExplorer::ToolChain *t) @@ -106,8 +93,9 @@ void CppProjectUpdater::onProjectInfoGenerated() if (m_generateFutureWatcher.isCanceled() || m_generateFutureWatcher.future().resultCount() < 1) return; - m_updateFuture = CppModelManager::instance()->updateProjectInfo( + auto updateFuture = CppModelManager::instance()->updateProjectInfo( m_generateFutureWatcher.result()); + m_futureSynchronizer.addFuture(updateFuture); } CppProjectUpdaterFactory::CppProjectUpdaterFactory() diff --git a/src/plugins/cpptools/cppprojectupdater.h b/src/plugins/cpptools/cppprojectupdater.h index f3f85a8a14f..6b994871ef9 100644 --- a/src/plugins/cpptools/cppprojectupdater.h +++ b/src/plugins/cpptools/cppprojectupdater.h @@ -29,6 +29,8 @@ #include "cpptools_global.h" #include "projectinfo.h" +#include + #include namespace CppTools { @@ -52,23 +54,19 @@ class CPPTOOLS_EXPORT CppProjectUpdater final : public QObject, public CppProjec public: CppProjectUpdater(); - ~CppProjectUpdater() override; void update(const ProjectExplorer::ProjectUpdateInfo &projectUpdateInfo) override; void cancel() override; private: - void cancelAndWaitForFinished(); - void onToolChainRemoved(ProjectExplorer::ToolChain *); void onProjectInfoGenerated(); private: ProjectExplorer::ProjectUpdateInfo m_projectUpdateInfo; - QFuture m_generateFuture; - QFuture m_updateFuture; QFutureWatcher m_generateFutureWatcher; + Utils::FutureSynchronizer m_futureSynchronizer; }; } // namespace CppTools