Process: Get rid of setTimeoutS()

Add an extra arg to runBlocking() function instead.
Use std::chrono::seconds for timeout.

Change-Id: I7c3c21e8f26a2ccbed157d15083d6ef0b4cd2f7e
Reviewed-by: Orgad Shaneh <orgads@gmail.com>
This commit is contained in:
Jarek Kobus
2024-01-22 17:27:24 +01:00
parent f6be85b1d2
commit afc67468e6
33 changed files with 68 additions and 115 deletions

View File

@@ -11,6 +11,8 @@
#include <set>
using namespace std::chrono_literals;
namespace Utils {
bool BuildableHelperLibrary::isQtChooser(const FilePath &filePath)
@@ -22,9 +24,8 @@ FilePath BuildableHelperLibrary::qtChooserToQmakePath(const FilePath &qtChooser)
{
const QString toolDir = QLatin1String("QTTOOLDIR=\"");
Process proc;
proc.setTimeoutS(1);
proc.setCommand({qtChooser, {"-print-env"}});
proc.runBlocking();
proc.runBlocking(1s);
if (proc.result() != ProcessResult::FinishedWithSuccess)
return {};
const QString output = proc.cleanedStdOut();
@@ -104,9 +105,8 @@ QString BuildableHelperLibrary::qtVersionForQMake(const FilePath &qmakePath)
return QString();
Process qmake;
qmake.setTimeoutS(5);
qmake.setCommand({qmakePath, {"--version"}});
qmake.runBlocking();
qmake.runBlocking(5s);
if (qmake.result() != ProcessResult::FinishedWithSuccess) {
qWarning() << qmake.exitMessage();
return QString();

View File

@@ -133,9 +133,8 @@ QString BinaryVersionToolTipEventFilter::toolVersion(const CommandLine &cmd)
if (cmd.executable().isEmpty())
return QString();
Process proc;
proc.setTimeoutS(1);
proc.setCommand(cmd);
proc.runBlocking();
proc.runBlocking(std::chrono::seconds(1));
if (proc.result() != ProcessResult::FinishedWithSuccess)
return QString();
return proc.allOutput();

View File

@@ -854,7 +854,6 @@ public:
time_point<system_clock, nanoseconds> m_startTimestamp = {};
time_point<system_clock, nanoseconds> m_doneTimestamp = {};
int m_timeoutInSeconds = 10;
bool m_timeOutMessageBoxEnabled = false;
Guard m_guard;
@@ -1847,14 +1846,6 @@ void ChannelBuffer::handleRest()
}
}
void Process::setTimeoutS(int timeoutS)
{
if (timeoutS > 0)
d->m_timeoutInSeconds = qMax(2, timeoutS);
else
d->m_timeoutInSeconds = INT_MAX / 1000;
}
void Process::setCodec(QTextCodec *c)
{
QTC_ASSERT(c, return);
@@ -1871,7 +1862,7 @@ void Process::setWriteData(const QByteArray &writeData)
d->m_setup.m_writeData = writeData;
}
void Process::runBlocking(EventLoopMode eventLoopMode)
void Process::runBlocking(seconds timeout, EventLoopMode eventLoopMode)
{
QDateTime startTime;
static const int blockingThresholdMs = qtcEnvironmentVariableIntValue("QTC_PROCESS_THRESHOLD");
@@ -1907,15 +1898,15 @@ void Process::runBlocking(EventLoopMode eventLoopMode)
QMetaObject::invokeMethod(this, handleStart, Qt::QueuedConnection);
std::function<void(void)> timeoutHandler = {};
if (d->m_timeoutInSeconds > 0) {
timeoutHandler = [this, &eventLoop, &timeoutHandler, &handleTimeout] {
if (timeout > seconds::zero()) {
timeoutHandler = [this, &eventLoop, &timeoutHandler, &handleTimeout, timeout] {
if (!d->m_timeOutMessageBoxEnabled || askToKill(d->m_setup.m_commandLine)) {
handleTimeout();
return;
}
QTimer::singleShot(d->m_timeoutInSeconds * 1000, &eventLoop, timeoutHandler);
QTimer::singleShot(timeout, &eventLoop, timeoutHandler);
};
QTimer::singleShot(d->m_timeoutInSeconds * 1000, &eventLoop, timeoutHandler);
QTimer::singleShot(timeout, &eventLoop, timeoutHandler);
}
connect(this, &Process::done, &eventLoop, [&eventLoop] { eventLoop.quit(); });
@@ -1927,7 +1918,7 @@ void Process::runBlocking(EventLoopMode eventLoopMode)
#endif
} else {
handleStart();
if (!waitForFinished(d->m_timeoutInSeconds * 1000))
if (!waitForFinished(duration_cast<milliseconds>(timeout).count()))
handleTimeout();
}
if (blockingThresholdMs > 0) {

View File

@@ -73,6 +73,7 @@ public:
QProcess::ProcessError error() const;
QString errorString() const;
// TODO: Change to std::chrono::milliseconds.
bool waitForStarted(int msecs = 30000);
bool waitForReadyRead(int msecs = 30000);
bool waitForFinished(int msecs = 30000);
@@ -144,11 +145,8 @@ public:
// Starts the command and waits for finish.
// User input processing is enabled when EventLoopMode::On was passed.
void runBlocking(EventLoopMode eventLoopMode = EventLoopMode::Off);
/* Timeout for hanging processes (triggers after no more output
* occurs on stderr/stdout). */
void setTimeoutS(int timeoutS);
void runBlocking(std::chrono::seconds timeout = std::chrono::seconds(10),
EventLoopMode eventLoopMode = EventLoopMode::Off);
// TODO: We should specify the purpose of the codec, e.g. setCodecForStandardChannel()
void setCodec(QTextCodec *c);

View File

@@ -220,9 +220,8 @@ static bool is32BitUserSpace()
if (HostOsInfo::isLinuxHost()) {
if (QSysInfo::WordSize == 32) {
Process proc;
proc.setTimeoutS(3);
proc.setCommand({"getconf", {"LONG_BIT"}});
proc.runBlocking();
proc.runBlocking(std::chrono::seconds(3));
if (proc.result() != ProcessResult::FinishedWithSuccess)
return true;
return proc.allOutput().trimmed() == "32";
@@ -312,7 +311,6 @@ bool AndroidAvdManager::isAvdBooted(const QString &device) const
const CommandLine command({m_config.adbToolPath(), arguments});
qCDebug(avdManagerLog).noquote() << "Running command (isAvdBooted):" << command.toUserOutput();
Process adbProc;
adbProc.setTimeoutS(10);
adbProc.setCommand(command);
adbProc.runBlocking();
if (adbProc.result() != ProcessResult::FinishedWithSuccess)

View File

@@ -999,9 +999,8 @@ QAbstractItemModel *AndroidBuildApkStep::keystoreCertificates()
"-storepass", m_keystorePasswd, "-J-Duser.language=en"};
Process keytoolProc;
keytoolProc.setTimeoutS(30);
keytoolProc.setCommand({AndroidConfigurations::currentConfig().keytoolPath(), params});
keytoolProc.runBlocking(EventLoopMode::On);
keytoolProc.runBlocking(std::chrono::seconds(30), EventLoopMode::On);
if (keytoolProc.result() > ProcessResult::FinishedWithError)
QMessageBox::critical(nullptr, Tr::tr("Error"), Tr::tr("Failed to run keytool."));
else

View File

@@ -9,7 +9,6 @@
#include "androidqtversion.h"
#include "androidtoolchain.h"
#include "androidtr.h"
#include "avddialog.h"
#include <coreplugin/icore.h>
#include <coreplugin/messagemanager.h>
@@ -598,10 +597,9 @@ QVector<AndroidDeviceInfo> AndroidConfig::connectedDevices(QString *error) const
{
QVector<AndroidDeviceInfo> devices;
Process adbProc;
adbProc.setTimeoutS(30);
CommandLine cmd{adbToolPath(), {"devices"}};
adbProc.setCommand(cmd);
adbProc.runBlocking();
adbProc.runBlocking(std::chrono::seconds(30));
if (adbProc.result() != ProcessResult::FinishedWithSuccess) {
if (error)
*error = Tr::tr("Could not run: %1").arg(cmd.toUserOutput());
@@ -667,7 +665,6 @@ QString AndroidConfig::getDeviceProperty(const QString &device, const QString &p
cmd.addArgs({"shell", "getprop", property});
Process adbProc;
adbProc.setTimeoutS(10);
adbProc.setCommand(cmd);
adbProc.runBlocking();
if (adbProc.result() != ProcessResult::FinishedWithSuccess)
@@ -744,7 +741,6 @@ QStringList AndroidConfig::getAbis(const QString &device)
QStringList arguments = AndroidDeviceInfo::adbSelector(device);
arguments << "shell" << "getprop" << "ro.product.cpu.abilist";
Process adbProc;
adbProc.setTimeoutS(10);
adbProc.setCommand({adbTool, arguments});
adbProc.runBlocking();
if (adbProc.result() != ProcessResult::FinishedWithSuccess)
@@ -767,7 +763,6 @@ QStringList AndroidConfig::getAbis(const QString &device)
arguments << QString::fromLatin1("ro.product.cpu.abi%1").arg(i);
Process abiProc;
abiProc.setTimeoutS(10);
abiProc.setCommand({adbTool, arguments});
abiProc.runBlocking();
if (abiProc.result() != ProcessResult::FinishedWithSuccess)

View File

@@ -273,9 +273,8 @@ void AndroidCreateKeystoreCertificate::buttonBoxAccepted()
"-dname", distinguishedNames});
Process genKeyCertProc;
genKeyCertProc.setTimeoutS(15);
genKeyCertProc.setCommand(command);
genKeyCertProc.runBlocking(EventLoopMode::On);
genKeyCertProc.runBlocking(std::chrono::seconds(15), EventLoopMode::On);
if (genKeyCertProc.result() != ProcessResult::FinishedWithSuccess) {
QMessageBox::critical(this, Tr::tr("Error"),

View File

@@ -572,12 +572,11 @@ Tasking::GroupItem AndroidDeployQtStep::runRecipe()
void AndroidDeployQtStep::runCommand(const CommandLine &command)
{
Process buildProc;
buildProc.setTimeoutS(2 * 60);
emit addOutput(Tr::tr("Package deploy: Running command \"%1\".").arg(command.toUserOutput()),
OutputFormat::NormalMessage);
buildProc.setCommand(command);
buildProc.runBlocking(EventLoopMode::On);
buildProc.runBlocking(std::chrono::minutes(2), EventLoopMode::On);
if (buildProc.result() != ProcessResult::FinishedWithSuccess)
reportWarningOrError(buildProc.exitMessage(), Task::Error);
}

View File

@@ -33,10 +33,11 @@
#include <QMessageBox>
#include <QVersionNumber>
using namespace Android::Internal;
using namespace ProjectExplorer;
using namespace Utils;
using namespace Android::Internal;
using namespace std::chrono_literals;
namespace Android::AndroidManager {
@@ -612,9 +613,8 @@ bool checkKeystorePassword(const FilePath &keystorePath, const QString &keystore
{"-list", "-keystore", keystorePath.toUserOutput(),
"--storepass", keystorePasswd});
Process proc;
proc.setTimeoutS(10);
proc.setCommand(cmd);
proc.runBlocking(EventLoopMode::On);
proc.runBlocking(10s, EventLoopMode::On);
return proc.result() == ProcessResult::FinishedWithSuccess;
}
@@ -630,9 +630,8 @@ bool checkCertificatePassword(const FilePath &keystorePath, const QString &keyst
arguments << certificatePasswd;
Process proc;
proc.setTimeoutS(10);
proc.setCommand({AndroidConfigurations::currentConfig().keytoolPath(), arguments});
proc.runBlocking(EventLoopMode::On);
proc.runBlocking(10s, EventLoopMode::On);
return proc.result() == ProcessResult::FinishedWithSuccess;
}
@@ -644,9 +643,8 @@ bool checkCertificateExists(const FilePath &keystorePath, const QString &keystor
"--storepass", keystorePasswd, "-alias", alias };
Process proc;
proc.setTimeoutS(10);
proc.setCommand({AndroidConfigurations::currentConfig().keytoolPath(), arguments});
proc.runBlocking(EventLoopMode::On);
proc.runBlocking(10s, EventLoopMode::On);
return proc.result() == ProcessResult::FinishedWithSuccess;
}
@@ -674,11 +672,10 @@ static SdkToolResult runCommand(const CommandLine &command, const QByteArray &wr
{
Android::SdkToolResult cmdResult;
Process cmdProc;
cmdProc.setTimeoutS(timeoutS);
cmdProc.setWriteData(writeData);
qCDebug(androidManagerLog) << "Running command (sync):" << command.toUserOutput();
cmdProc.setCommand(command);
cmdProc.runBlocking(EventLoopMode::On);
cmdProc.runBlocking(std::chrono::seconds(timeoutS), EventLoopMode::On);
cmdResult.m_stdOut = cmdProc.cleanedStdOut().trimmed();
cmdResult.m_stdErr = cmdProc.cleanedStdErr().trimmed();
cmdResult.m_success = cmdProc.result() == ProcessResult::FinishedWithSuccess;

View File

@@ -26,10 +26,11 @@ const char commonArgsKey[] = "Common Arguments:";
using namespace Utils;
using namespace std::chrono;
namespace Android {
namespace Internal {
const int sdkManagerCmdTimeoutS = 60;
const int sdkManagerOperationTimeoutS = 600;
@@ -94,10 +95,9 @@ static bool sdkManagerCommand(const AndroidConfig &config, const QStringList &ar
.toUserOutput();
Process proc;
proc.setEnvironment(config.toolsEnvironment());
proc.setTimeoutS(timeout);
proc.setTimeOutMessageBoxEnabled(true);
proc.setCommand({config.sdkManagerToolPath(), newArgs});
proc.runBlocking(EventLoopMode::On);
proc.runBlocking(seconds(timeout), EventLoopMode::On);
if (output)
*output = proc.allOutput();
return proc.result() == ProcessResult::FinishedWithSuccess;
@@ -123,7 +123,6 @@ static void sdkManagerCommand(const AndroidConfig &config, const QStringList &ar
Process proc;
proc.setEnvironment(config.toolsEnvironment());
bool assertionFound = false;
proc.setTimeoutS(timeout);
proc.setStdOutCallback([offset, progressQuota, &proc, &assertionFound, &promise](const QString &out) {
int progressPercent = parseProgress(out, assertionFound);
if (assertionFound) {
@@ -143,7 +142,7 @@ static void sdkManagerCommand(const AndroidConfig &config, const QStringList &ar
});
}
proc.setCommand({config.sdkManagerToolPath(), newArgs});
proc.runBlocking(EventLoopMode::On);
proc.runBlocking(seconds(timeout), EventLoopMode::On);
if (assertionFound) {
output.success = false;
output.stdOutput = proc.cleanedStdOut();

View File

@@ -71,7 +71,6 @@ static Macros dumpPredefinedMacros(const FilePath &compiler, const QStringList &
Process cpp;
cpp.setEnvironment(env);
cpp.setTimeoutS(10);
CommandLine cmd(compiler, {fakeIn.fileName()});
if (languageId == ProjectExplorer::Constants::CXX_LANGUAGE_ID)
@@ -123,7 +122,6 @@ static HeaderPaths dumpHeaderPaths(const FilePath &compiler, const Id languageId
Process cpp;
cpp.setEnvironment(env);
cpp.setTimeoutS(10);
cpp.setCommand(cmd);
cpp.runBlocking();

View File

@@ -106,7 +106,6 @@ static Macros dumpMcsPredefinedMacros(const FilePath &compiler, const Environmen
Process cpp;
cpp.setEnvironment(env);
cpp.setTimeoutS(10);
cpp.setCommand({compiler, {fakeIn.fileName()}});
cpp.runBlocking();
@@ -183,7 +182,6 @@ static Macros dumpC166PredefinedMacros(const FilePath &compiler, const Environme
Process cpp;
cpp.setEnvironment(env);
cpp.setTimeoutS(10);
Macros macros;
auto extractMacros = [&macros](const QString &output) {
@@ -248,7 +246,6 @@ static Macros dumpArmPredefinedMacros(const FilePath &compiler, const QStringLis
{
Process cpp;
cpp.setEnvironment(env);
cpp.setTimeoutS(10);
QStringList args = extraArgs;
args.push_back("-E");

View File

@@ -60,7 +60,6 @@ static Macros dumpPredefinedMacros(const FilePath &compiler, const Environment &
Process cpp;
cpp.setEnvironment(env);
cpp.setTimeoutS(10);
cpp.setCommand({compiler, {compilerTargetFlag(abi), "-dM", "-E", fakeIn.fileName()}});
cpp.runBlocking();
@@ -81,7 +80,6 @@ static HeaderPaths dumpHeaderPaths(const FilePath &compiler, const Environment &
Process cpp;
cpp.setEnvironment(env);
cpp.setTimeoutS(10);
cpp.setCommand({compiler, {compilerTargetFlag(abi), "--print-search-dirs"}});
cpp.runBlocking();

View File

@@ -96,9 +96,8 @@ public:
void createDocumentationFile() const final
{
Process process;
process.setTimeoutS(2);
process.setCommand({command(), {"-h"}});
process.runBlocking();
process.runBlocking(std::chrono::seconds(2));
if (process.result() != ProcessResult::FinishedWithSuccess)
return;

View File

@@ -100,9 +100,8 @@ public:
void createDocumentationFile() const final
{
Process process;
process.setTimeoutS(2);
process.setCommand({command(), {"--show-config"}});
process.runBlocking();
process.runBlocking(std::chrono::seconds(2));
if (process.result() != ProcessResult::FinishedWithSuccess)
return;

View File

@@ -1621,8 +1621,7 @@ CommandResult ClearCasePluginPrivate::runCleartoolProc(const FilePath &workingDi
process.setEnvironment(env);
process.setCommand({m_settings.ccBinaryPath, arguments});
process.setWorkingDirectory(workingDir);
process.setTimeoutS(m_settings.timeOutS);
process.runBlocking();
process.runBlocking(std::chrono::seconds(m_settings.timeOutS));
return CommandResult(process);
}
@@ -2284,11 +2283,10 @@ QString ClearCasePluginPrivate::runExtDiff(const FilePath &workingDir, const QSt
diff.addArgs(arguments);
Process process;
process.setTimeoutS(timeOutS);
process.setWorkingDirectory(workingDir);
process.setCodec(outputCodec ? outputCodec : QTextCodec::codecForName("UTF-8"));
process.setCommand(diff);
process.runBlocking(EventLoopMode::On);
process.runBlocking(std::chrono::seconds(timeOutS), EventLoopMode::On);
if (process.result() != ProcessResult::FinishedWithSuccess)
return {};
return process.allOutput();

View File

@@ -34,6 +34,8 @@ using namespace ProjectExplorer;
using namespace QtSupport;
using namespace Utils;
using namespace std::chrono_literals;
namespace CMakeProjectManager::Internal {
static Q_LOGGING_CATEGORY(cmInputLog, "qtc.cmake.import", QtWarningMsg);
@@ -215,7 +217,6 @@ static CMakeConfig configurationFromPresetProbe(
"\n"));
Process cmake;
cmake.setTimeoutS(30);
cmake.setDisableUnixTerminal();
const FilePath cmakeExecutable = FilePath::fromString(configurePreset.cmakeExecutable.value());
@@ -290,7 +291,7 @@ static CMakeConfig configurationFromPresetProbe(
qCDebug(cmInputLog) << "CMake probing for compilers: " << cmakeExecutable.toUserOutput()
<< args;
cmake.setCommand({cmakeExecutable, args});
cmake.runBlocking();
cmake.runBlocking(30s);
QString errorMessage;
const CMakeConfig config = CMakeConfig::fromFile(importPath.pathAppended(
@@ -395,7 +396,6 @@ static QMakeAndCMakePrefixPath qtInfoFromCMakeCache(const CMakeConfig &config,
)"));
Process cmake;
cmake.setTimeoutS(5);
cmake.setDisableUnixTerminal();
Environment cmakeEnv(env);
@@ -447,7 +447,7 @@ static QMakeAndCMakePrefixPath qtInfoFromCMakeCache(const CMakeConfig &config,
qCDebug(cmInputLog) << "CMake probing for qmake path: " << cmakeExecutable.toUserOutput() << args;
cmake.setCommand({cmakeExecutable, args});
cmake.runBlocking();
cmake.runBlocking(5s);
const FilePath qmakeLocationTxt = qtcQMakeProbeDir.filePath("qmake-location.txt");
const FilePath qmakeLocation = FilePath::fromUtf8(

View File

@@ -169,13 +169,12 @@ bool CMakeTool::isValid(bool ignoreCache) const
void CMakeTool::runCMake(Process &cmake, const QStringList &args, int timeoutS) const
{
const FilePath executable = cmakeExecutable();
cmake.setTimeoutS(timeoutS);
cmake.setDisableUnixTerminal();
Environment env = executable.deviceEnvironment();
env.setupEnglishOutput();
cmake.setEnvironment(env);
cmake.setCommand({executable, args});
cmake.runBlocking();
cmake.runBlocking(std::chrono::seconds(timeoutS));
}
Store CMakeTool::toMap() const

View File

@@ -365,9 +365,8 @@ static std::function<void(FilePath)> postCopyOperation()
// On macOS, downloaded files get a quarantine flag, remove it, otherwise it is a hassle
// to get it loaded as a plugin in Qt Creator.
Process xattr;
xattr.setTimeoutS(1);
xattr.setCommand({"/usr/bin/xattr", {"-d", "com.apple.quarantine", filePath.absoluteFilePath().toString()}});
xattr.runBlocking();
xattr.runBlocking(std::chrono::seconds(1));
};
}

View File

@@ -620,9 +620,8 @@ void DebuggerItemModel::autoDetectGdbOrLldbDebuggers(const FilePaths &searchPath
if (searchPaths.front().osType() == OsTypeMac) {
Process proc;
proc.setTimeoutS(2);
proc.setCommand({"xcrun", {"--find", "lldb"}});
proc.runBlocking();
proc.runBlocking(std::chrono::seconds(2));
// FIXME:
if (proc.result() == ProcessResult::FinishedWithSuccess) {
QString lPath = proc.allOutput().trimmed();

View File

@@ -215,10 +215,9 @@ static QByteArray decodeProvisioningProfile(const QString &path)
QTC_ASSERT(!path.isEmpty(), return QByteArray());
Process p;
p.setTimeoutS(3);
// path is assumed to be valid file path to .mobileprovision
p.setCommand({"openssl", {"smime", "-inform", "der", "-verify", "-in", path}});
p.runBlocking();
p.runBlocking(std::chrono::seconds(3));
if (p.result() != ProcessResult::FinishedWithSuccess)
qCDebug(iosCommonLog) << "Reading signed provisioning file failed" << path;
return p.cleanedStdOut().toLatin1();

View File

@@ -41,9 +41,8 @@ void XcodeProbe::addDeveloperPath(const QString &path)
void XcodeProbe::detectDeveloperPaths()
{
Utils::Process selectedXcode;
selectedXcode.setTimeoutS(5);
selectedXcode.setCommand({"/usr/bin/xcode-select", {"--print-path"}});
selectedXcode.runBlocking();
selectedXcode.runBlocking(std::chrono::seconds(5));
if (selectedXcode.result() != ProcessResult::FinishedWithSuccess)
qCWarning(probeLog)
<< QString::fromLatin1("Could not detect selected Xcode using xcode-select");

View File

@@ -1187,7 +1187,6 @@ PerforceResponse PerforcePluginPrivate::synchronousProcess(const FilePath &worki
Process process;
process.setWriteData(stdInput);
const int timeOutS = (flags & LongTimeOut) ? settings().longTimeOutS() : settings().timeOutS();
process.setTimeoutS(timeOutS);
if (outputCodec)
process.setCodec(outputCodec);
if (flags & OverrideDiffEnvironment)
@@ -1208,7 +1207,8 @@ PerforceResponse PerforcePluginPrivate::synchronousProcess(const FilePath &worki
}
process.setTimeOutMessageBoxEnabled(true);
process.setCommand({settings().p4BinaryPath(), args});
process.runBlocking(flags & RunFullySynchronous ? EventLoopMode::Off : EventLoopMode::On);
process.runBlocking(std::chrono::seconds(timeOutS),
flags & RunFullySynchronous ? EventLoopMode::Off : EventLoopMode::On);
const auto result = process.result();
PerforceResponse response;

View File

@@ -88,13 +88,12 @@ static bool
arguments.push_back(value);
}
process.setWorkingDirectory(workingDirectory);
process.setTimeoutS(30);
const Utils::CommandLine cmd(FilePath::fromString(binary), arguments);
if (CustomWizard::verbose())
qDebug("In %s, running:\n%s\n", qPrintable(workingDirectory.toUserOutput()),
qPrintable(cmd.toUserOutput()));
process.setCommand(cmd);
process.runBlocking(EventLoopMode::On);
process.runBlocking(std::chrono::seconds(30), EventLoopMode::On);
if (process.result() != Utils::ProcessResult::FinishedWithSuccess) {
*errorMessage = QString("Generator script failed: %1").arg(process.exitMessage());
const QString stdErr = process.cleanedStdErr();

View File

@@ -167,7 +167,6 @@ static QString runGcc(const FilePath &gcc, const QStringList &arguments, const E
environment.setupEnglishOutput();
cpp.setEnvironment(environment);
cpp.setTimeoutS(10);
cpp.setCommand({gcc, arguments});
cpp.runBlocking();
if (cpp.result() != ProcessResult::FinishedWithSuccess || cpp.exitCode() != 0) {

View File

@@ -44,6 +44,8 @@
using namespace Utils;
using namespace std::chrono_literals;
#define KEY_ROOT "ProjectExplorer.MsvcToolChain."
static const char varsBatKeyC[] = KEY_ROOT "VarsBat";
static const char varsBatArgKeyC[] = KEY_ROOT "VarsBatArg";
@@ -256,10 +258,9 @@ static QVector<VisualStudioInstallation> detectVisualStudioFromVsWhere(const QSt
QVector<VisualStudioInstallation> installations;
Process vsWhereProcess;
vsWhereProcess.setCodec(QTextCodec::codecForName("UTF-8"));
vsWhereProcess.setTimeoutS(5);
vsWhereProcess.setCommand({FilePath::fromString(vswhere),
{"-products", "*", "-prerelease", "-legacy", "-format", "json", "-utf8"}});
vsWhereProcess.runBlocking();
vsWhereProcess.runBlocking(5s);
if (vsWhereProcess.result() != ProcessResult::FinishedWithSuccess) {
qWarning() << vsWhereProcess.exitMessage();
return installations;
@@ -2124,7 +2125,6 @@ std::optional<QString> MsvcToolChain::generateEnvironmentSettings(const Utils::E
Utils::Environment runEnv = env;
runEnv.unset(QLatin1String("ORIGINALPATH"));
run.setEnvironment(runEnv);
run.setTimeoutS(60);
Utils::FilePath cmdPath = Utils::FilePath::fromUserInput(qtcEnvironmentVariable("COMSPEC"));
if (cmdPath.isEmpty())
cmdPath = env.searchInPath(QLatin1String("cmd.exe"));
@@ -2134,7 +2134,7 @@ std::optional<QString> MsvcToolChain::generateEnvironmentSettings(const Utils::E
<< " Env: " << runEnv.toStringList().size();
run.setCodec(QTextCodec::codecForName("UTF-8"));
run.setCommand(cmd);
run.runBlocking();
run.runBlocking(1min);
if (run.result() != ProcessResult::FinishedWithSuccess) {
const QString message = !run.cleanedStdErr().isEmpty() ? run.cleanedStdErr() : run.exitMessage();

View File

@@ -85,9 +85,8 @@ static PythonLanguageServerState checkPythonLanguageServer(const FilePath &pytho
return {PythonLanguageServerState::AlreadyInstalled, lspPath};
Process pythonProcess;
pythonProcess.setTimeoutS(2);
pythonProcess.setCommand({python, {"-m", "pip", "-V"}});
pythonProcess.runBlocking();
pythonProcess.runBlocking(std::chrono::seconds(2));
if (pythonProcess.allOutput().startsWith("pip "))
return {PythonLanguageServerState::CanBeInstalled, lspPath};
return {PythonLanguageServerState::CanNotBeInstalled, FilePath()};

View File

@@ -70,9 +70,8 @@ static Interpreter createInterpreter(const FilePath &python,
Process pythonProcess;
pythonProcess.setProcessChannelMode(QProcess::MergedChannels);
pythonProcess.setTimeoutS(1);
pythonProcess.setCommand({python, {"--version"}});
pythonProcess.runBlocking();
pythonProcess.runBlocking(std::chrono::seconds(1));
if (pythonProcess.result() == ProcessResult::FinishedWithSuccess)
result.name = pythonProcess.cleanedStdOut().trimmed();
if (result.name.isEmpty())

View File

@@ -148,9 +148,8 @@ QString pythonName(const FilePath &pythonPath)
QString name = nameForPython.value(pythonPath);
if (name.isEmpty()) {
Process pythonProcess;
pythonProcess.setTimeoutS(2);
pythonProcess.setCommand({pythonPath, {"--version"}});
pythonProcess.runBlocking();
pythonProcess.runBlocking(std::chrono::seconds(2));
if (pythonProcess.result() != ProcessResult::FinishedWithSuccess)
return {};
name = pythonProcess.allOutput().trimmed();

View File

@@ -65,9 +65,8 @@ static FormatTask format(FormatTask task)
QStringList options = task.command.options();
options.replaceInStrings(QLatin1String("%file"), sourceFile.filePath().toString());
Process process;
process.setTimeoutS(5);
process.setCommand({executable, options});
process.runBlocking();
process.runBlocking(std::chrono::seconds(5));
if (process.result() != ProcessResult::FinishedWithSuccess) {
task.error = Tr::tr("Failed to format: %1.").arg(process.exitMessage());
return task;

View File

@@ -297,6 +297,7 @@ CommandResult VcsCommand::runBlocking(const FilePath &workingDirectory,
return vcsCommand.runBlockingHelper(command, timeoutS);
}
// TODO: change timeout to std::chrono::seconds
CommandResult VcsCommand::runBlockingHelper(const CommandLine &command, int timeoutS)
{
Process process;
@@ -305,11 +306,10 @@ CommandResult VcsCommand::runBlockingHelper(const CommandLine &command, int time
const Internal::VcsCommandPrivate::Job job{command, timeoutS, d->m_defaultWorkingDirectory};
d->setupProcess(&process, job);
process.setTimeoutS(timeoutS);
const EventLoopMode eventLoopMode = d->eventLoopMode();
process.setTimeOutMessageBoxEnabled(eventLoopMode == EventLoopMode::On);
process.runBlocking(eventLoopMode);
process.runBlocking(std::chrono::seconds(timeoutS), eventLoopMode);
d->handleDone(&process, job);
return CommandResult(process);

View File

@@ -25,6 +25,9 @@
using namespace Utils;
using namespace std::chrono;
using namespace std::chrono_literals;
// This handler is inspired by the one used in qtbase/tests/auto/corelib/io/qfile/tst_qfile.cpp
class MessageHandler {
public:
@@ -943,33 +946,32 @@ void tst_Process::exitCode()
void tst_Process::runBlockingStdOut_data()
{
QTest::addColumn<bool>("withEndl");
QTest::addColumn<int>("timeOutS");
QTest::addColumn<seconds>("timeout");
QTest::addColumn<ProcessResult>("expectedResult");
// Canceled, since the process is killed (canceled) from the callback.
QTest::newRow("Short timeout with end of line") << true << 2 << ProcessResult::Canceled;
QTest::newRow("Short timeout with end of line") << true << 2s << ProcessResult::Canceled;
// Canceled, since it times out.
QTest::newRow("Short timeout without end of line") << false << 2 << ProcessResult::Canceled;
QTest::newRow("Short timeout without end of line") << false << 2s << ProcessResult::Canceled;
// FinishedWithSuccess, since it doesn't time out, it finishes process normally,
// calls the callback handler and tries to stop the process forcefully what is no-op
// at this point in time since the process is already finished.
QTest::newRow("Long timeout without end of line")
<< false << 20 << ProcessResult::FinishedWithSuccess;
<< false << 20s << ProcessResult::FinishedWithSuccess;
}
void tst_Process::runBlockingStdOut()
{
QFETCH(bool, withEndl);
QFETCH(int, timeOutS);
QFETCH(seconds, timeout);
QFETCH(ProcessResult, expectedResult);
SubProcessConfig subConfig(ProcessTestApp::RunBlockingStdOut::envVar(), withEndl ? "true" : "false");
Process process;
subConfig.setupSubProcess(&process);
process.setTimeoutS(timeOutS);
bool readLastLine = false;
process.setStdOutCallback([&readLastLine, &process](const QString &out) {
if (out.startsWith(s_runBlockingStdOutSubProcessMagicWord)) {
@@ -977,7 +979,7 @@ void tst_Process::runBlockingStdOut()
process.kill();
}
});
process.runBlocking();
process.runBlocking(timeout);
// See also QTCREATORBUG-25667 for why it is a bad idea to use Process::runBlocking
// with interactive cli tools.
@@ -993,14 +995,13 @@ void tst_Process::runBlockingSignal_data()
void tst_Process::runBlockingSignal()
{
QFETCH(bool, withEndl);
QFETCH(int, timeOutS);
QFETCH(seconds, timeout);
QFETCH(ProcessResult, expectedResult);
SubProcessConfig subConfig(ProcessTestApp::RunBlockingStdOut::envVar(), withEndl ? "true" : "false");
Process process;
subConfig.setupSubProcess(&process);
process.setTimeoutS(timeOutS);
bool readLastLine = false;
process.setTextChannelMode(Channel::Output, TextChannelMode::MultiLine);
connect(&process, &Process::textOnStandardOutput,
@@ -1010,7 +1011,7 @@ void tst_Process::runBlockingSignal()
process.kill();
}
});
process.runBlocking();
process.runBlocking(timeout);
// See also QTCREATORBUG-25667 for why it is a bad idea to use Process::runBlocking
// with interactive cli tools.
@@ -1593,7 +1594,7 @@ void tst_Process::eventLoopMode()
Process process;
subConfig.setupSubProcess(&process);
process.setProcessImpl(processImpl);
process.runBlocking(eventLoopMode);
process.runBlocking(10s, eventLoopMode);
QCOMPARE(process.result(), ProcessResult::FinishedWithSuccess);
}
@@ -1602,7 +1603,7 @@ void tst_Process::eventLoopMode()
process.setCommand({FilePath::fromString(
"there_is_a_big_chance_that_executable_with_that_name_does_not_exists"), {} });
process.setProcessImpl(processImpl);
process.runBlocking(eventLoopMode);
process.runBlocking(10s, eventLoopMode);
QCOMPARE(process.result(), ProcessResult::StartFailed);
}
}