diff --git a/src/plugins/remotelinux/linuxdevice.cpp b/src/plugins/remotelinux/linuxdevice.cpp index 95275ba282e..a61a5586d66 100644 --- a/src/plugins/remotelinux/linuxdevice.cpp +++ b/src/plugins/remotelinux/linuxdevice.cpp @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include @@ -376,14 +377,49 @@ public: void attachToSharedConnection(SshConnectionHandle *connectionHandle, const SshParameters &sshParameters); + Environment getEnvironment(); + void invalidateEnvironmentCache(); + LinuxDevice *q = nullptr; QThread m_shellThread; ShellThreadHandler *m_handler = nullptr; mutable QMutex m_shellMutex; QList m_terminals; LinuxDeviceFileAccess m_fileAccess{this}; + + QReadWriteLock m_environmentCacheLock; + std::optional m_environmentCache; }; +void LinuxDevicePrivate::invalidateEnvironmentCache() +{ + QWriteLocker locker(&m_environmentCacheLock); + m_environmentCache.reset(); +} + +Environment LinuxDevicePrivate::getEnvironment() +{ + QReadLocker locker(&m_environmentCacheLock); + if (m_environmentCache.has_value()) + return m_environmentCache.value(); + + locker.unlock(); + QWriteLocker writeLocker(&m_environmentCacheLock); + if (m_environmentCache.has_value()) + return m_environmentCache.value(); + + QtcProcess getEnvProc; + getEnvProc.setCommand({FilePath("env").onDevice(q->rootPath()), {}}); + Environment inEnv; + inEnv.setCombineWithDeviceEnvironment(false); + getEnvProc.setEnvironment(inEnv); + getEnvProc.runBlocking(); + + const QString remoteOutput = getEnvProc.cleanedStdOut(); + m_environmentCache = Environment(remoteOutput.split('\n', Qt::SkipEmptyParts), q->osType()); + return m_environmentCache.value(); +} + RunResult LinuxDeviceFileAccess::runInShell(const CommandLine &cmdLine, const QByteArray &stdInData) const { @@ -392,15 +428,7 @@ RunResult LinuxDeviceFileAccess::runInShell(const CommandLine &cmdLine, Environment LinuxDeviceFileAccess::deviceEnvironment() const { - QtcProcess getEnvProc; - getEnvProc.setCommand({FilePath("env").onDevice(m_dev->q->rootPath()), {}}); - Environment inEnv; - inEnv.setCombineWithDeviceEnvironment(false); - getEnvProc.setEnvironment(inEnv); - getEnvProc.runBlocking(); - - const QString remoteOutput = getEnvProc.cleanedStdOut(); - return Environment(remoteOutput.split('\n', Qt::SkipEmptyParts), m_dev->q->osType()); + return m_dev->getEnvironment(); } // SshProcessImpl @@ -1126,6 +1154,8 @@ bool LinuxDevicePrivate::setupShell() if (m_handler->isRunning(sshParameters)) return true; + invalidateEnvironmentCache(); + bool ok = false; QMetaObject::invokeMethod(m_handler, [this, sshParameters] { return m_handler->start(sshParameters);