From b851b57ea3cbe777f8e0894db46a2489704aa84d Mon Sep 17 00:00:00 2001 From: Tobias Hunger Date: Mon, 4 Jul 2016 17:20:23 +0200 Subject: [PATCH] Utils::ShellCommand: Force fully synchronous execution from UI thread Force runCommand when run from the UI thread to do fully synchronous operations. This prevents two event loops in one thread with (sometimes) interesting side effects. This also stops signals from being sent while the process is running, but the remaining users seem to be able to handle that. Change-Id: Id5eb9868b660419987730c60e3fbfb4cbced1218 Reviewed-by: Orgad Shaneh --- src/libs/utils/shellcommand.cpp | 3 ++- src/libs/utils/shellcommand.h | 6 ++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/libs/utils/shellcommand.cpp b/src/libs/utils/shellcommand.cpp index f95985492dd..49b6134a11c 100644 --- a/src/libs/utils/shellcommand.cpp +++ b/src/libs/utils/shellcommand.cpp @@ -39,6 +39,7 @@ #include #include #include +#include #include /*! @@ -326,7 +327,7 @@ Utils::SynchronousProcessResponse ShellCommand::runCommand(const Utils::FileName if (!(d->m_flags & SuppressCommandLogging)) proxy->appendCommand(dir, binary, arguments); - if (d->m_flags & FullySynchronously) + if (d->m_flags & FullySynchronously || QThread::currentThread() == QCoreApplication::instance()->thread()) response = runFullySynchronous(binary, arguments, proxy.data(), timeoutS, dir, interpreter); else response = runSynchronous(binary, arguments, proxy.data(), timeoutS, dir, interpreter); diff --git a/src/libs/utils/shellcommand.h b/src/libs/utils/shellcommand.h index 480865154b4..58527c4fe39 100644 --- a/src/libs/utils/shellcommand.h +++ b/src/libs/utils/shellcommand.h @@ -140,6 +140,9 @@ public: void setOutputProxyFactory(const std::function &factory); + // This is called once per job in a thread. + // When called from the UI thread it will execute fully synchronously, so no signals will + // be triggered! virtual SynchronousProcessResponse runCommand(const FileName &binary, const QStringList &arguments, int timeoutS, const QString &workingDirectory = QString(), @@ -162,10 +165,13 @@ protected: private: void run(QFutureInterface &future); + + // Run without a event loop in fully blocking mode. No signals will be delivered. SynchronousProcessResponse runFullySynchronous(const FileName &binary, const QStringList &arguments, OutputProxy *proxy, int timeoutS, const QString &workingDirectory, const ExitCodeInterpreter &interpreter = defaultExitCodeInterpreter); + // Run with an event loop. Signals will be delivered. SynchronousProcessResponse runSynchronous(const FileName &binary, const QStringList &arguments, OutputProxy *proxy, int timeoutS, const QString &workingDirectory,