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 a30aa4421a
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 a30aa4421a

Fixes: QTCREATORBUG-25970
Change-Id: I6836c97038c36968e93815c6121bc284edbe19bb
Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
This commit is contained in:
Eike Ziller
2021-07-08 13:01:36 +02:00
parent 9a9b4080ae
commit 4767dfcce3
2 changed files with 22 additions and 14 deletions

View File

@@ -284,8 +284,11 @@ QmakeBuildSystem::~QmakeBuildSystem()
delete m_qmakeVfs; delete m_qmakeVfs;
m_qmakeVfs = nullptr; m_qmakeVfs = nullptr;
m_asyncUpdateFutureInterface.reportCanceled(); if (m_asyncUpdateFutureInterface) {
m_asyncUpdateFutureInterface.reportFinished(); m_asyncUpdateFutureInterface->reportCanceled();
m_asyncUpdateFutureInterface->reportFinished();
m_asyncUpdateFutureInterface.reset();
}
} }
void QmakeBuildSystem::updateCodeModels() void QmakeBuildSystem::updateCodeModels()
@@ -592,8 +595,9 @@ void QmakeBuildSystem::incrementPendingEvaluateFutures()
} }
++m_pendingEvaluateFuturesCount; ++m_pendingEvaluateFuturesCount;
TRACE("pending inc to: " << m_pendingEvaluateFuturesCount); TRACE("pending inc to: " << m_pendingEvaluateFuturesCount);
m_asyncUpdateFutureInterface.setProgressRange(m_asyncUpdateFutureInterface.progressMinimum(), m_asyncUpdateFutureInterface->setProgressRange(m_asyncUpdateFutureInterface->progressMinimum(),
m_asyncUpdateFutureInterface.progressMaximum() + 1); m_asyncUpdateFutureInterface->progressMaximum()
+ 1);
} }
void QmakeBuildSystem::decrementPendingEvaluateFutures() void QmakeBuildSystem::decrementPendingEvaluateFutures()
@@ -606,15 +610,17 @@ void QmakeBuildSystem::decrementPendingEvaluateFutures()
return; // We are closing the project! return; // We are closing the project!
} }
m_asyncUpdateFutureInterface.setProgressValue(m_asyncUpdateFutureInterface.progressValue() + 1); m_asyncUpdateFutureInterface->setProgressValue(m_asyncUpdateFutureInterface->progressValue()
+ 1);
if (m_pendingEvaluateFuturesCount == 0) { if (m_pendingEvaluateFuturesCount == 0) {
// We are done! // We are done!
setRootProjectNode(QmakeNodeTreeBuilder::buildTree(this)); setRootProjectNode(QmakeNodeTreeBuilder::buildTree(this));
if (!m_rootProFile->validParse()) if (!m_rootProFile->validParse())
m_asyncUpdateFutureInterface.reportCanceled(); m_asyncUpdateFutureInterface->reportCanceled();
m_asyncUpdateFutureInterface.reportFinished(); m_asyncUpdateFutureInterface->reportFinished();
m_asyncUpdateFutureInterface.reset();
m_cancelEvaluate = false; m_cancelEvaluate = false;
// TODO clear the profile cache ? // TODO clear the profile cache ?
@@ -660,12 +666,13 @@ void QmakeBuildSystem::asyncUpdate()
m_qmakeVfs->invalidateCache(); m_qmakeVfs->invalidateCache();
} }
m_asyncUpdateFutureInterface.setProgressRange(0, 0); m_asyncUpdateFutureInterface.reset(new QFutureInterface<void>);
Core::ProgressManager::addTask(m_asyncUpdateFutureInterface.future(), m_asyncUpdateFutureInterface->setProgressRange(0, 0);
Core::ProgressManager::addTask(m_asyncUpdateFutureInterface->future(),
tr("Reading Project \"%1\"").arg(project()->displayName()), tr("Reading Project \"%1\"").arg(project()->displayName()),
Constants::PROFILE_EVALUATE); Constants::PROFILE_EVALUATE);
m_asyncUpdateFutureInterface.reportStarted(); m_asyncUpdateFutureInterface->reportStarted();
const auto watcher = new QFutureWatcher<void>(this); const auto watcher = new QFutureWatcher<void>(this);
connect(watcher, &QFutureWatcher<void>::canceled, this, [this, watcher] { connect(watcher, &QFutureWatcher<void>::canceled, this, [this, watcher] {
if (!m_qmakeGlobals) if (!m_qmakeGlobals)
@@ -677,7 +684,7 @@ void QmakeBuildSystem::asyncUpdate()
watcher->disconnect(); watcher->disconnect();
watcher->deleteLater(); watcher->deleteLater();
}); });
watcher->setFuture(m_asyncUpdateFutureInterface.future()); watcher->setFuture(m_asyncUpdateFutureInterface->future());
const Kit *const k = kit(); const Kit *const k = kit();
QtSupport::BaseQtVersion *const qtVersion = QtSupport::QtKitAspect::qtVersion(k); QtSupport::BaseQtVersion *const qtVersion = QtSupport::QtKitAspect::qtVersion(k);
@@ -688,8 +695,9 @@ void QmakeBuildSystem::asyncUpdate()
.arg(project()->displayName(), k->displayName()) .arg(project()->displayName(), k->displayName())
: tr("Cannot parse project \"%1\": No kit selected.").arg(project()->displayName()); : tr("Cannot parse project \"%1\": No kit selected.").arg(project()->displayName());
proFileParseError(errorMessage, project()->projectFilePath()); proFileParseError(errorMessage, project()->projectFilePath());
m_asyncUpdateFutureInterface.reportCanceled(); m_asyncUpdateFutureInterface->reportCanceled();
m_asyncUpdateFutureInterface.reportFinished(); m_asyncUpdateFutureInterface->reportFinished();
m_asyncUpdateFutureInterface.reset();
return; return;
} }

View File

@@ -198,7 +198,7 @@ private:
QString m_qmakeSysroot; QString m_qmakeSysroot;
QFutureInterface<void> m_asyncUpdateFutureInterface; std::unique_ptr<QFutureInterface<void>> m_asyncUpdateFutureInterface;
int m_pendingEvaluateFuturesCount = 0; int m_pendingEvaluateFuturesCount = 0;
AsyncUpdateState m_asyncUpdateState = Base; AsyncUpdateState m_asyncUpdateState = Base;
bool m_cancelEvaluate = false; bool m_cancelEvaluate = false;