From 4767dfcce32ca69d88861f5ab8a18b0a1110b0b4 Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Thu, 8 Jul 2021 13:01:36 +0200 Subject: [PATCH] qmake: Fix issues with executing system calls Do not try to reuse the QFutureInterface that is used for the parsing process. Reusing the QFutureInterface can lead to issues. So far no problems were triggered, but a30aa4421a0257b048197b51330e6bf5c2732af5 introduced a watcher that tells the qmake parser to ignore all system calls after the future was canceled. This was somehow, sometimes triggered on the reused QFutureInterface even though the user didn't cancel anyhing, leading to all system calls to bail out in the subsequent run. Using a new QFutureInterface instance for each parsing run solves the issue. Amends a30aa4421a0257b048197b51330e6bf5c2732af5 Fixes: QTCREATORBUG-25970 Change-Id: I6836c97038c36968e93815c6121bc284edbe19bb Reviewed-by: Christian Kandeler --- .../qmakeprojectmanager/qmakeproject.cpp | 34 ++++++++++++------- .../qmakeprojectmanager/qmakeproject.h | 2 +- 2 files changed, 22 insertions(+), 14 deletions(-) diff --git a/src/plugins/qmakeprojectmanager/qmakeproject.cpp b/src/plugins/qmakeprojectmanager/qmakeproject.cpp index 387c0688a4b..f62398a315c 100644 --- a/src/plugins/qmakeprojectmanager/qmakeproject.cpp +++ b/src/plugins/qmakeprojectmanager/qmakeproject.cpp @@ -284,8 +284,11 @@ QmakeBuildSystem::~QmakeBuildSystem() delete m_qmakeVfs; m_qmakeVfs = nullptr; - m_asyncUpdateFutureInterface.reportCanceled(); - m_asyncUpdateFutureInterface.reportFinished(); + if (m_asyncUpdateFutureInterface) { + m_asyncUpdateFutureInterface->reportCanceled(); + m_asyncUpdateFutureInterface->reportFinished(); + m_asyncUpdateFutureInterface.reset(); + } } void QmakeBuildSystem::updateCodeModels() @@ -592,8 +595,9 @@ void QmakeBuildSystem::incrementPendingEvaluateFutures() } ++m_pendingEvaluateFuturesCount; TRACE("pending inc to: " << m_pendingEvaluateFuturesCount); - m_asyncUpdateFutureInterface.setProgressRange(m_asyncUpdateFutureInterface.progressMinimum(), - m_asyncUpdateFutureInterface.progressMaximum() + 1); + m_asyncUpdateFutureInterface->setProgressRange(m_asyncUpdateFutureInterface->progressMinimum(), + m_asyncUpdateFutureInterface->progressMaximum() + + 1); } void QmakeBuildSystem::decrementPendingEvaluateFutures() @@ -606,15 +610,17 @@ void QmakeBuildSystem::decrementPendingEvaluateFutures() return; // We are closing the project! } - m_asyncUpdateFutureInterface.setProgressValue(m_asyncUpdateFutureInterface.progressValue() + 1); + m_asyncUpdateFutureInterface->setProgressValue(m_asyncUpdateFutureInterface->progressValue() + + 1); if (m_pendingEvaluateFuturesCount == 0) { // We are done! setRootProjectNode(QmakeNodeTreeBuilder::buildTree(this)); if (!m_rootProFile->validParse()) - m_asyncUpdateFutureInterface.reportCanceled(); + m_asyncUpdateFutureInterface->reportCanceled(); - m_asyncUpdateFutureInterface.reportFinished(); + m_asyncUpdateFutureInterface->reportFinished(); + m_asyncUpdateFutureInterface.reset(); m_cancelEvaluate = false; // TODO clear the profile cache ? @@ -660,12 +666,13 @@ void QmakeBuildSystem::asyncUpdate() m_qmakeVfs->invalidateCache(); } - m_asyncUpdateFutureInterface.setProgressRange(0, 0); - Core::ProgressManager::addTask(m_asyncUpdateFutureInterface.future(), + m_asyncUpdateFutureInterface.reset(new QFutureInterface); + m_asyncUpdateFutureInterface->setProgressRange(0, 0); + Core::ProgressManager::addTask(m_asyncUpdateFutureInterface->future(), tr("Reading Project \"%1\"").arg(project()->displayName()), Constants::PROFILE_EVALUATE); - m_asyncUpdateFutureInterface.reportStarted(); + m_asyncUpdateFutureInterface->reportStarted(); const auto watcher = new QFutureWatcher(this); connect(watcher, &QFutureWatcher::canceled, this, [this, watcher] { if (!m_qmakeGlobals) @@ -677,7 +684,7 @@ void QmakeBuildSystem::asyncUpdate() watcher->disconnect(); watcher->deleteLater(); }); - watcher->setFuture(m_asyncUpdateFutureInterface.future()); + watcher->setFuture(m_asyncUpdateFutureInterface->future()); const Kit *const k = kit(); QtSupport::BaseQtVersion *const qtVersion = QtSupport::QtKitAspect::qtVersion(k); @@ -688,8 +695,9 @@ void QmakeBuildSystem::asyncUpdate() .arg(project()->displayName(), k->displayName()) : tr("Cannot parse project \"%1\": No kit selected.").arg(project()->displayName()); proFileParseError(errorMessage, project()->projectFilePath()); - m_asyncUpdateFutureInterface.reportCanceled(); - m_asyncUpdateFutureInterface.reportFinished(); + m_asyncUpdateFutureInterface->reportCanceled(); + m_asyncUpdateFutureInterface->reportFinished(); + m_asyncUpdateFutureInterface.reset(); return; } diff --git a/src/plugins/qmakeprojectmanager/qmakeproject.h b/src/plugins/qmakeprojectmanager/qmakeproject.h index fba8c8db7a5..89397407abb 100644 --- a/src/plugins/qmakeprojectmanager/qmakeproject.h +++ b/src/plugins/qmakeprojectmanager/qmakeproject.h @@ -198,7 +198,7 @@ private: QString m_qmakeSysroot; - QFutureInterface m_asyncUpdateFutureInterface; + std::unique_ptr> m_asyncUpdateFutureInterface; int m_pendingEvaluateFuturesCount = 0; AsyncUpdateState m_asyncUpdateState = Base; bool m_cancelEvaluate = false;