aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEike Ziller <eike.ziller@qt.io>2021-05-31 13:38:41 +0200
committerCristian Adam <cristian.adam@qt.io>2021-05-31 13:58:26 +0000
commitfbeaa774b5528764669f8cf2068b65149fc4adcd (patch)
tree2f51276d1e49801e92e7ee0387c36c0cc8c19e98
parent637a20c34c4cb7890625bfded77e14654128acf1 (diff)
CMakePM: stop file api reader future on stop()
The future that would trigger the result of a cmake api file parsing would not be removed if the stop parsing would be triggered. This could be triggered by fast switching between build configurations. It could also lead to forever parsing states having the project's wheel always spinning. Fixes: QTCREATORBUG-25588 Fixes: QTCREATORBUG-25287 Change-Id: I4f92806ebdb703b4910952cd8db1e52816daf9cf Reviewed-by: Cristian Adam <cristian.adam@qt.io> Reviewed-by: Eike Ziller <eike.ziller@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
-rw-r--r--src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp3
-rw-r--r--src/plugins/cmakeprojectmanager/fileapireader.cpp54
-rw-r--r--src/plugins/cmakeprojectmanager/fileapireader.h4
3 files changed, 36 insertions, 25 deletions
diff --git a/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp b/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp
index 30a393c0b6..0fe4bfe3b3 100644
--- a/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp
+++ b/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp
@@ -904,7 +904,8 @@ FilePath CMakeBuildSystem::workDirectory(const BuildDirParameters &parameters)
void CMakeBuildSystem::stopParsingAndClearState()
{
- qCDebug(cmakeBuildSystemLog) << "stopping parsing run!";
+ qCDebug(cmakeBuildSystemLog) << cmakeBuildConfiguration()->displayName()
+ << "stopping parsing run!";
m_reader.stop();
m_reader.resetData();
}
diff --git a/src/plugins/cmakeprojectmanager/fileapireader.cpp b/src/plugins/cmakeprojectmanager/fileapireader.cpp
index ae3725e4a8..2b3a086b1e 100644
--- a/src/plugins/cmakeprojectmanager/fileapireader.cpp
+++ b/src/plugins/cmakeprojectmanager/fileapireader.cpp
@@ -165,6 +165,13 @@ void FileApiReader::stop()
if (m_cmakeProcess)
disconnect(m_cmakeProcess.get(), nullptr, this, nullptr);
m_cmakeProcess.reset();
+
+ if (m_future) {
+ m_future->cancel();
+ m_future->waitForFinished();
+ }
+ m_future = {};
+ m_isParsing = false;
}
bool FileApiReader::isParsing() const
@@ -259,7 +266,7 @@ void FileApiReader::endState(const QFileInfo &replyFi)
m_future = runAsync(ProjectExplorerPlugin::sharedThreadPool(),
[replyFi, sourceDirectory, buildDirectory, topCmakeFile, cmakeBuildType]() {
- auto result = std::make_unique<FileApiQtcData>();
+ auto result = std::make_shared<FileApiQtcData>();
FileApiData data = FileApiParser::parseData(replyFi, cmakeBuildType, result->errorMessage);
if (!result->errorMessage.isEmpty()) {
qWarning() << result->errorMessage;
@@ -274,29 +281,30 @@ void FileApiReader::endState(const QFileInfo &replyFi)
qWarning() << result->errorMessage;
}
- return result.release();
+ return result;
});
- onFinished(m_future.value(), this, [this](const QFuture<FileApiQtcData *> &f) {
- std::unique_ptr<FileApiQtcData> value(f.result()); // Adopt the pointer again:-)
-
- m_future = {};
- m_isParsing = false;
- m_cache = std::move(value->cache);
- m_cmakeFiles = std::move(value->cmakeFiles);
- m_buildTargets = std::move(value->buildTargets);
- m_projectParts = std::move(value->projectParts);
- m_rootProjectNode = std::move(value->rootProjectNode);
- m_knownHeaders = std::move(value->knownHeaders);
- m_ctestPath = std::move(value->ctestPath);
- m_isMultiConfig = std::move(value->isMultiConfig);
- m_usesAllCapsTargets = std::move(value->usesAllCapsTargets);
-
- if (value->errorMessage.isEmpty()) {
- emit this->dataAvailable();
- } else {
- emit this->errorOccurred(value->errorMessage);
- }
- });
+ onResultReady(m_future.value(),
+ this,
+ [this, topCmakeFile, sourceDirectory, buildDirectory](
+ const std::shared_ptr<FileApiQtcData> &value) {
+ m_isParsing = false;
+ m_cache = std::move(value->cache);
+ m_cmakeFiles = std::move(value->cmakeFiles);
+ m_buildTargets = std::move(value->buildTargets);
+ m_projectParts = std::move(value->projectParts);
+ m_rootProjectNode = std::move(value->rootProjectNode);
+ m_knownHeaders = std::move(value->knownHeaders);
+ m_ctestPath = std::move(value->ctestPath);
+ m_isMultiConfig = std::move(value->isMultiConfig);
+ m_usesAllCapsTargets = std::move(value->usesAllCapsTargets);
+
+ if (value->errorMessage.isEmpty()) {
+ emit this->dataAvailable();
+ } else {
+ emit this->errorOccurred(value->errorMessage);
+ }
+ m_future = {};
+ });
}
void FileApiReader::makeBackupConfiguration(bool store)
diff --git a/src/plugins/cmakeprojectmanager/fileapireader.h b/src/plugins/cmakeprojectmanager/fileapireader.h
index 25d5e1af1b..505f5fd506 100644
--- a/src/plugins/cmakeprojectmanager/fileapireader.h
+++ b/src/plugins/cmakeprojectmanager/fileapireader.h
@@ -38,6 +38,8 @@
#include <QObject>
#include <QDateTime>
+#include <memory>
+
namespace ProjectExplorer {
class ProjectNode;
}
@@ -105,7 +107,7 @@ private:
bool m_usesAllCapsTargets = false;
int m_lastCMakeExitCode = 0;
- Utils::optional<QFuture<FileApiQtcData *>> m_future;
+ Utils::optional<QFuture<std::shared_ptr<FileApiQtcData>>> m_future;
// Update related:
bool m_isParsing = false;