diff options
author | Eike Ziller <eike.ziller@qt.io> | 2020-11-10 17:55:54 +0100 |
---|---|---|
committer | Eike Ziller <eike.ziller@qt.io> | 2020-11-11 12:49:33 +0000 |
commit | 6d7e5eb8d17194b124c8986d670ff96fda96f0f3 (patch) | |
tree | d798aee5f50a97d59dd3458afdceb04c0978fbe7 /src/plugins/cpptools/cppprojectupdater.cpp | |
parent | 557a09ba4c4c232f1f7095ed9c6889f0abc919f0 (diff) | |
download | qt-creator-6d7e5eb8d17194b124c8986d670ff96fda96f0f3.tar.gz |
Fix CppProjectUpdater cancelAndWaitForFinished
The code was pushing an additional QFutureInterface through the whole
chain of functions, which was used for canceling. But since it was never
started (and never finished, and never used for reporting results),
calling waitForFinshed on it never had any effect with Qt5 and locks up
with Qt6.
Instead of using a separate QFutureInterface, use the actual QFuture
that is available and intended for it.
Fixes: QTCREATORBUG-24902
Change-Id: I5a49bcecc9cf70fbffa93aee4293004f9369df58
Reviewed-by: Jarek Kobus <jaroslaw.kobus@qt.io>
Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
Diffstat (limited to 'src/plugins/cpptools/cppprojectupdater.cpp')
-rw-r--r-- | src/plugins/cpptools/cppprojectupdater.cpp | 31 |
1 files changed, 18 insertions, 13 deletions
diff --git a/src/plugins/cpptools/cppprojectupdater.cpp b/src/plugins/cpptools/cppprojectupdater.cpp index d17c260930..c56b2666f0 100644 --- a/src/plugins/cpptools/cppprojectupdater.cpp +++ b/src/plugins/cpptools/cppprojectupdater.cpp @@ -37,8 +37,10 @@ namespace CppTools { CppProjectUpdater::CppProjectUpdater() { - connect(&m_generateFutureWatcher, &QFutureWatcher<void>::finished, - this, &CppProjectUpdater::onProjectInfoGenerated); + connect(&m_generateFutureWatcher, + &QFutureWatcher<ProjectInfo>::finished, + this, + &CppProjectUpdater::onProjectInfoGenerated); } CppProjectUpdater::~CppProjectUpdater() @@ -50,7 +52,6 @@ void CppProjectUpdater::update(const ProjectExplorer::ProjectUpdateInfo &project { // Stop previous update. cancelAndWaitForFinished(); - m_futureInterface = QFutureInterface<void>(); m_projectUpdateInfo = projectUpdateInfo; @@ -60,26 +61,30 @@ 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. - const QFuture<ProjectInfo> future = Utils::runAsync([=]() { + m_generateFuture = Utils::runAsync([=](QFutureInterface<ProjectInfo> &futureInterface) { ProjectUpdateInfo fullProjectUpdateInfo = projectUpdateInfo; if (fullProjectUpdateInfo.rppGenerator) fullProjectUpdateInfo.rawProjectParts = fullProjectUpdateInfo.rppGenerator(); - Internal::ProjectInfoGenerator generator(m_futureInterface, fullProjectUpdateInfo); - return generator.generate(); + Internal::ProjectInfoGenerator generator(futureInterface, fullProjectUpdateInfo); + futureInterface.reportResult(generator.generate()); }); - m_generateFutureWatcher.setFuture(future); + m_generateFutureWatcher.setFuture(m_generateFuture); } void CppProjectUpdater::cancel() { - disconnect(&m_generateFutureWatcher); - m_futureInterface.cancel(); + m_generateFutureWatcher.setFuture({}); + m_generateFuture.cancel(); + m_updateFuture.cancel(); } void CppProjectUpdater::cancelAndWaitForFinished() { cancel(); - m_futureInterface.waitForFinished(); + if (m_generateFuture.isRunning()) + m_generateFuture.waitForFinished(); + if (m_updateFuture.isRunning()) + m_updateFuture.waitForFinished(); } void CppProjectUpdater::onToolChainRemoved(ProjectExplorer::ToolChain *t) @@ -96,11 +101,11 @@ void CppProjectUpdater::onProjectInfoGenerated() disconnect(ToolChainManager::instance(), &ToolChainManager::toolChainRemoved, this, &CppProjectUpdater::onToolChainRemoved); - if (m_futureInterface.isCanceled()) + if (m_generateFutureWatcher.isCanceled() || m_generateFutureWatcher.future().resultCount() < 1) return; - QFuture<void> future = CppModelManager::instance() - ->updateProjectInfo(m_futureInterface, m_generateFutureWatcher.result()); + m_updateFuture = CppModelManager::instance()->updateProjectInfo( + m_generateFutureWatcher.result()); } CppProjectUpdaterFactory::CppProjectUpdaterFactory() |