From 2bfec17bef59a0f07c873614034288bb169b92cc Mon Sep 17 00:00:00 2001 From: David Schulz Date: Tue, 6 Feb 2018 09:34:50 +0100 Subject: [PATCH] ProjectExplorer: run vcvars bat in parallel Instead of collecting the environment differences for all MsvcToolChain when needed, start an async job at object construction. This reduces the blocking startup time depending on the Toolchain count up to 8 seconds. Change-Id: Ie004956f290d7555f88226c7f4d9f7eb37ec2261 Reviewed-by: Tobias Hunger --- src/plugins/projectexplorer/msvctoolchain.cpp | 50 ++++++++++++++----- src/plugins/projectexplorer/msvctoolchain.h | 8 ++- 2 files changed, 45 insertions(+), 13 deletions(-) diff --git a/src/plugins/projectexplorer/msvctoolchain.cpp b/src/plugins/projectexplorer/msvctoolchain.cpp index a64b749e33c..d603f82e544 100644 --- a/src/plugins/projectexplorer/msvctoolchain.cpp +++ b/src/plugins/projectexplorer/msvctoolchain.cpp @@ -27,15 +27,17 @@ #include "msvcparser.h" #include "projectexplorerconstants.h" +#include "toolchainmanager.h" #include +#include +#include +#include #include #include -#include -#include -#include +#include #include -#include +#include #include #include @@ -520,13 +522,14 @@ static QString winExpandDelayedEnvReferences(QString in, const Utils::Environmen return in; } -QList MsvcToolChain::environmentModifications() const +void MsvcToolChain::environmentModifications(QFutureInterface> &future, + QString vcvarsBat, QString varsBatArg) { const Utils::Environment inEnv = Utils::Environment::systemEnvironment(); Utils::Environment outEnv; QMap envPairs; - if (!generateEnvironmentSettings(inEnv, m_vcvarsBat, m_varsBatArg, envPairs)) - return QList(); + if (!generateEnvironmentSettings(inEnv, vcvarsBat, varsBatArg, envPairs)) + return; // Now loop through and process them for (auto envIter = envPairs.cbegin(), eend = envPairs.cend(); envIter != eend; ++envIter) { @@ -552,13 +555,21 @@ QList MsvcToolChain::environmentModifications() const } } - return diff; + future.reportResult(diff); +} + +void MsvcToolChain::initEnvModWatcher(const QFuture > &future) +{ + QObject::connect(&m_envModWatcher, &QFutureWatcherBase::resultReadyAt, [&]() { + m_environmentModifications = m_envModWatcher.result(); + }); + m_envModWatcher.setFuture(future); } Utils::Environment MsvcToolChain::readEnvironmentSetting(const Utils::Environment& env) const { - if (m_environmentModifications.isEmpty()) - m_environmentModifications = environmentModifications(); + if (m_environmentModifications.isEmpty() && m_envModWatcher.isRunning()) + m_envModWatcher.waitForFinished(); Utils::Environment result = env; result.modify(m_environmentModifications); return result; @@ -574,11 +585,26 @@ MsvcToolChain::MsvcToolChain(const QString &name, const Abi &abi, MsvcToolChain(Constants::MSVC_TOOLCHAIN_TYPEID, name, abi, varsBat, varsBatArg, l, d) { } +MsvcToolChain::MsvcToolChain(const MsvcToolChain &other) + : AbstractMsvcToolChain(other.typeId(), other.language(), other.detection(), other.targetAbi(), other.varsBat()) + , m_environmentModifications(other.m_environmentModifications) + , m_varsBatArg(other.m_varsBatArg) +{ + if (!other.m_envModWatcher.isRunning()) + initEnvModWatcher(other.m_envModWatcher.future()); + + setDisplayName(other.displayName()); +} + MsvcToolChain::MsvcToolChain(Core::Id typeId, const QString &name, const Abi &abi, const QString &varsBat, const QString &varsBatArg, Core::Id l, - Detection d) : AbstractMsvcToolChain(typeId, l, d, abi, varsBat), - m_varsBatArg(varsBatArg) + Detection d) + : AbstractMsvcToolChain(typeId, l, d, abi, varsBat) + , m_varsBatArg(varsBatArg) { + initEnvModWatcher(Utils::runAsync(&MsvcToolChain::environmentModifications, + varsBat, varsBatArg)); + Q_ASSERT(!name.isEmpty()); setDisplayName(name); diff --git a/src/plugins/projectexplorer/msvctoolchain.h b/src/plugins/projectexplorer/msvctoolchain.h index 3dcb715286a..8a44658004e 100644 --- a/src/plugins/projectexplorer/msvctoolchain.h +++ b/src/plugins/projectexplorer/msvctoolchain.h @@ -29,6 +29,8 @@ #include "abi.h" #include "toolchainconfigwidget.h" +#include + QT_FORWARD_DECLARE_CLASS(QLabel) QT_FORWARD_DECLARE_CLASS(QVersionNumber) @@ -57,6 +59,7 @@ public: explicit MsvcToolChain(const QString &name, const Abi &abi, const QString &varsBat, const QString &varsBatArg, Core::Id l, Detection d = ManualDetection); + MsvcToolChain(const MsvcToolChain &other); MsvcToolChain(); Utils::FileNameList suggestedMkspecList() const override; @@ -86,9 +89,12 @@ protected: const Utils::Environment &env) const override; private: - QList environmentModifications() const; + static void environmentModifications(QFutureInterface > &future, + QString vcvarsBat, QString varsBatArg); + void initEnvModWatcher(const QFuture> &future); mutable QList m_environmentModifications; + mutable QFutureWatcher> m_envModWatcher; QString m_varsBatArg; // Argument };