From 2ac65f863bf9fedaf199e77f901cf8d5affc5061 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Mon, 25 Oct 2021 11:18:49 +0200 Subject: [PATCH] Refactor the lifetime of future watcher inside QmakeProFile Create future watcher only prior to starting an async task. After the task is done, clean the watcher in order to release the resources kept inside its QFuture's result. Make setupFutureWatcher() a private member. Provide a corresponding cleanupFutureWatcher(). Change-Id: I9d2b058250a3f749a2c9ad51323d2d38f66ee98d Reviewed-by: Christian Kandeler --- .../qmakeprojectmanager/qmakeparsernodes.cpp | 40 ++++++++++--------- .../qmakeprojectmanager/qmakeparsernodes.h | 7 ++-- 2 files changed, 24 insertions(+), 23 deletions(-) diff --git a/src/plugins/qmakeprojectmanager/qmakeparsernodes.cpp b/src/plugins/qmakeprojectmanager/qmakeparsernodes.cpp index 95b634a8f36..0931743f9b4 100644 --- a/src/plugins/qmakeprojectmanager/qmakeparsernodes.cpp +++ b/src/plugins/qmakeprojectmanager/qmakeparsernodes.cpp @@ -1174,7 +1174,6 @@ QByteArray QmakeProFile::cxxDefines() const QmakeProFile::QmakeProFile(QmakeBuildSystem *buildSystem, const FilePath &filePath) : QmakePriFile(buildSystem, this, filePath) { - setupFutureWatcher(); } QmakeProFile::QmakeProFile(const FilePath &filePath) : QmakePriFile(filePath) { } @@ -1182,22 +1181,33 @@ QmakeProFile::QmakeProFile(const FilePath &filePath) : QmakePriFile(filePath) { QmakeProFile::~QmakeProFile() { qDeleteAll(m_extraCompilers); - if (m_parseFutureWatcher) { - m_parseFutureWatcher->cancel(); - m_parseFutureWatcher->waitForFinished(); - if (m_readerExact) - applyAsyncEvaluate(false); - delete m_parseFutureWatcher; - } + cleanupFutureWatcher(); cleanupProFileReaders(); } +void QmakeProFile::cleanupFutureWatcher() +{ + if (!m_parseFutureWatcher) + return; + + m_parseFutureWatcher->disconnect(); + m_parseFutureWatcher->cancel(); + m_parseFutureWatcher->waitForFinished(); + m_parseFutureWatcher->deleteLater(); + m_parseFutureWatcher = nullptr; + m_buildSystem->decrementPendingEvaluateFutures(); +} + void QmakeProFile::setupFutureWatcher() { + QTC_ASSERT(!m_parseFutureWatcher, return); + m_parseFutureWatcher = new QFutureWatcher; QObject::connect(m_parseFutureWatcher, &QFutureWatcherBase::finished, [this]() { - applyAsyncEvaluate(true); + applyEvaluate(m_parseFutureWatcher->result()); + cleanupFutureWatcher(); }); + m_buildSystem->incrementPendingEvaluateFutures(); } bool QmakeProFile::isParent(QmakeProFile *node) @@ -1286,11 +1296,11 @@ void QmakeProFile::scheduleUpdate(QmakeProFile::AsyncUpdateDelay delay) void QmakeProFile::asyncUpdate() { - m_buildSystem->incrementPendingEvaluateFutures(); + cleanupFutureWatcher(); + setupFutureWatcher(); setupReader(); if (!includedInExactParse()) m_readerExact->setExact(false); - m_parseFutureWatcher->waitForFinished(); QmakeEvalInput input = evalInput(); QFuture future = Utils::runAsync(ProjectExplorerPlugin::sharedThreadPool(), QThread::LowestPriority, @@ -1640,13 +1650,6 @@ void QmakeProFile::asyncEvaluate(QFutureInterface &fi, Qmake fi.reportResult(evaluate(input)); } -void QmakeProFile::applyAsyncEvaluate(bool apply) -{ - if (apply) - applyEvaluate(m_parseFutureWatcher->result()); - m_buildSystem->decrementPendingEvaluateFutures(); -} - bool sortByParserNodes(Node *a, Node *b) { return a->filePath() < b->filePath(); @@ -1720,7 +1723,6 @@ void QmakeProFile::applyEvaluate(const QmakeEvalResultPtr &result) for (QmakeProFile * const proFile : qAsConst(result->proFiles)) { proFile->finishInitialization(m_buildSystem, proFile); - proFile->setupFutureWatcher(); proFile->asyncUpdate(); } QmakePriFile::update(result->includedFiles.result); diff --git a/src/plugins/qmakeprojectmanager/qmakeparsernodes.h b/src/plugins/qmakeprojectmanager/qmakeparsernodes.h index a894a11cc4c..2dab66fdc96 100644 --- a/src/plugins/qmakeprojectmanager/qmakeparsernodes.h +++ b/src/plugins/qmakeprojectmanager/qmakeparsernodes.h @@ -306,8 +306,6 @@ public: explicit QmakeProFile(const Utils::FilePath &filePath); ~QmakeProFile() override; - void setupFutureWatcher(); - bool isParent(QmakeProFile *node); QString displayName() const final; @@ -351,11 +349,12 @@ public: bool isFileFromWildcard(const QString &filePath) const; private: + void cleanupFutureWatcher(); + void setupFutureWatcher(); + void setParseInProgress(bool b); void setValidParseRecursive(bool b); - void applyAsyncEvaluate(bool apply); - void setupReader(); Internal::QmakeEvalInput evalInput() const;