forked from qt-creator/qt-creator
Utils: Make SynchronousProcess use second based timeouts
Change-Id: Ie2de2359225017cae7181bee0df17542fa36efd8 Reviewed-by: Tobias Hunger <tobias.hunger@theqtcompany.com>
This commit is contained in:
committed by
Tobias Hunger
parent
5a2b5036ab
commit
a79df8e1e7
@@ -211,7 +211,7 @@ bool BuildableHelperLibrary::copyFiles(const QString &sourcePath,
|
|||||||
static inline bool runBuildProcessI(QProcess &proc,
|
static inline bool runBuildProcessI(QProcess &proc,
|
||||||
const FileName &binary,
|
const FileName &binary,
|
||||||
const QStringList &args,
|
const QStringList &args,
|
||||||
int timeoutMS,
|
int timeoutS,
|
||||||
bool ignoreNonNullExitCode,
|
bool ignoreNonNullExitCode,
|
||||||
QString *output, QString *errorMessage)
|
QString *output, QString *errorMessage)
|
||||||
{
|
{
|
||||||
@@ -225,10 +225,10 @@ static inline bool runBuildProcessI(QProcess &proc,
|
|||||||
// Read stdout/err and check for timeouts
|
// Read stdout/err and check for timeouts
|
||||||
QByteArray stdOut;
|
QByteArray stdOut;
|
||||||
QByteArray stdErr;
|
QByteArray stdErr;
|
||||||
if (!SynchronousProcess::readDataFromProcess(proc, timeoutMS, &stdOut, &stdErr, false)) {
|
if (!SynchronousProcess::readDataFromProcess(proc, timeoutS, &stdOut, &stdErr, false)) {
|
||||||
*errorMessage = QCoreApplication::translate("ProjectExplorer::BuildableHelperLibrary",
|
*errorMessage = QCoreApplication::translate("ProjectExplorer::BuildableHelperLibrary",
|
||||||
"Timeout after %1 s.").
|
"Timeout after %1 s.").
|
||||||
arg(timeoutMS / 1000);
|
arg(timeoutS);
|
||||||
SynchronousProcess::stopProcess(proc);
|
SynchronousProcess::stopProcess(proc);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -252,11 +252,11 @@ static inline bool runBuildProcessI(QProcess &proc,
|
|||||||
static bool runBuildProcess(QProcess &proc,
|
static bool runBuildProcess(QProcess &proc,
|
||||||
const FileName &binary,
|
const FileName &binary,
|
||||||
const QStringList &args,
|
const QStringList &args,
|
||||||
int timeoutMS,
|
int timeoutS,
|
||||||
bool ignoreNonNullExitCode,
|
bool ignoreNonNullExitCode,
|
||||||
QString *output, QString *errorMessage)
|
QString *output, QString *errorMessage)
|
||||||
{
|
{
|
||||||
const bool rc = runBuildProcessI(proc, binary, args, timeoutMS, ignoreNonNullExitCode, output, errorMessage);
|
const bool rc = runBuildProcessI(proc, binary, args, timeoutS, ignoreNonNullExitCode, output, errorMessage);
|
||||||
if (!rc) {
|
if (!rc) {
|
||||||
// Fail - reformat error.
|
// Fail - reformat error.
|
||||||
QString cmd = binary.toString();
|
QString cmd = binary.toString();
|
||||||
@@ -300,7 +300,7 @@ bool BuildableHelperLibrary::buildHelper(const BuildHelperArguments &arguments,
|
|||||||
log->append(QCoreApplication::translate("ProjectExplorer::BuildableHelperLibrary",
|
log->append(QCoreApplication::translate("ProjectExplorer::BuildableHelperLibrary",
|
||||||
"Running %1 %2...\n")
|
"Running %1 %2...\n")
|
||||||
.arg(makeFullPath.toUserOutput(), cleanTarget));
|
.arg(makeFullPath.toUserOutput(), cleanTarget));
|
||||||
if (!runBuildProcess(proc, makeFullPath, QStringList(cleanTarget), 30000, true, log, errorMessage))
|
if (!runBuildProcess(proc, makeFullPath, QStringList(cleanTarget), 30, true, log, errorMessage))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
QStringList qmakeArgs;
|
QStringList qmakeArgs;
|
||||||
@@ -316,7 +316,7 @@ bool BuildableHelperLibrary::buildHelper(const BuildHelperArguments &arguments,
|
|||||||
"Running %1 %2 ...\n").arg(arguments.qmakeCommand.toUserOutput(),
|
"Running %1 %2 ...\n").arg(arguments.qmakeCommand.toUserOutput(),
|
||||||
qmakeArgs.join(QLatin1Char(' '))));
|
qmakeArgs.join(QLatin1Char(' '))));
|
||||||
|
|
||||||
if (!runBuildProcess(proc, arguments.qmakeCommand, qmakeArgs, 30000, false, log, errorMessage))
|
if (!runBuildProcess(proc, arguments.qmakeCommand, qmakeArgs, 30, false, log, errorMessage))
|
||||||
return false;
|
return false;
|
||||||
log->append(newline);
|
log->append(newline);
|
||||||
if (makeFullPath.isEmpty()) {
|
if (makeFullPath.isEmpty()) {
|
||||||
@@ -327,7 +327,7 @@ bool BuildableHelperLibrary::buildHelper(const BuildHelperArguments &arguments,
|
|||||||
log->append(QCoreApplication::translate("ProjectExplorer::BuildableHelperLibrary",
|
log->append(QCoreApplication::translate("ProjectExplorer::BuildableHelperLibrary",
|
||||||
"Running %1 %2 ...\n")
|
"Running %1 %2 ...\n")
|
||||||
.arg(makeFullPath.toUserOutput(), arguments.makeArguments.join(QLatin1Char(' '))));
|
.arg(makeFullPath.toUserOutput(), arguments.makeArguments.join(QLatin1Char(' '))));
|
||||||
if (!runBuildProcess(proc, makeFullPath, arguments.makeArguments, 120000, false, log, errorMessage))
|
if (!runBuildProcess(proc, makeFullPath, arguments.makeArguments, 120, false, log, errorMessage))
|
||||||
return false;
|
return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -124,7 +124,7 @@ void SynchronousProcessResponse::clear()
|
|||||||
stdErr.clear();
|
stdErr.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString SynchronousProcessResponse::exitMessage(const QString &binary, int timeoutMS) const
|
QString SynchronousProcessResponse::exitMessage(const QString &binary, int timeoutS) const
|
||||||
{
|
{
|
||||||
switch (result) {
|
switch (result) {
|
||||||
case Finished:
|
case Finished:
|
||||||
@@ -136,8 +136,8 @@ QString SynchronousProcessResponse::exitMessage(const QString &binary, int timeo
|
|||||||
case StartFailed:
|
case StartFailed:
|
||||||
return SynchronousProcess::tr("The command \"%1\" could not be started.").arg(QDir::toNativeSeparators(binary));
|
return SynchronousProcess::tr("The command \"%1\" could not be started.").arg(QDir::toNativeSeparators(binary));
|
||||||
case Hang:
|
case Hang:
|
||||||
return SynchronousProcess::tr("The command \"%1\" did not respond within the timeout limit (%2 ms).").
|
return SynchronousProcess::tr("The command \"%1\" did not respond within the timeout limit (%2 s).")
|
||||||
arg(QDir::toNativeSeparators(binary)).arg(timeoutMS);
|
.arg(QDir::toNativeSeparators(binary)).arg(timeoutS);
|
||||||
}
|
}
|
||||||
return QString();
|
return QString();
|
||||||
}
|
}
|
||||||
@@ -268,17 +268,17 @@ SynchronousProcess::~SynchronousProcess()
|
|||||||
delete d;
|
delete d;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SynchronousProcess::setTimeout(int timeoutMS)
|
void SynchronousProcess::setTimeoutS(int timeoutS)
|
||||||
{
|
{
|
||||||
if (timeoutMS >= 0)
|
if (timeoutS >= 0)
|
||||||
d->m_maxHangTimerCount = qMax(2, timeoutMS / 1000);
|
d->m_maxHangTimerCount = qMax(2, timeoutS);
|
||||||
else
|
else
|
||||||
d->m_maxHangTimerCount = INT_MAX;
|
d->m_maxHangTimerCount = INT_MAX;
|
||||||
}
|
}
|
||||||
|
|
||||||
int SynchronousProcess::timeout() const
|
int SynchronousProcess::timeoutS() const
|
||||||
{
|
{
|
||||||
return d->m_maxHangTimerCount == INT_MAX ? -1 : 1000 * d->m_maxHangTimerCount;
|
return d->m_maxHangTimerCount == INT_MAX ? -1 : d->m_maxHangTimerCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SynchronousProcess::setCodec(QTextCodec *c)
|
void SynchronousProcess::setCodec(QTextCodec *c)
|
||||||
@@ -582,12 +582,12 @@ QSharedPointer<QProcess> SynchronousProcess::createProcess(unsigned flags)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Static utilities: Keep running as long as it gets data.
|
// Static utilities: Keep running as long as it gets data.
|
||||||
bool SynchronousProcess::readDataFromProcess(QProcess &p, int timeOutMS,
|
bool SynchronousProcess::readDataFromProcess(QProcess &p, int timeoutS,
|
||||||
QByteArray *stdOut, QByteArray *stdErr,
|
QByteArray *stdOut, QByteArray *stdErr,
|
||||||
bool showTimeOutMessageBox)
|
bool showTimeOutMessageBox)
|
||||||
{
|
{
|
||||||
if (syncDebug)
|
if (syncDebug)
|
||||||
qDebug() << ">readDataFromProcess" << timeOutMS;
|
qDebug() << ">readDataFromProcess" << timeoutS;
|
||||||
if (p.state() != QProcess::Running) {
|
if (p.state() != QProcess::Running) {
|
||||||
qWarning("readDataFromProcess: Process in non-running state passed in.");
|
qWarning("readDataFromProcess: Process in non-running state passed in.");
|
||||||
return false;
|
return false;
|
||||||
@@ -599,7 +599,7 @@ bool SynchronousProcess::readDataFromProcess(QProcess &p, int timeOutMS,
|
|||||||
bool finished = false;
|
bool finished = false;
|
||||||
bool hasData = false;
|
bool hasData = false;
|
||||||
do {
|
do {
|
||||||
finished = p.state() == QProcess::NotRunning || p.waitForFinished(timeOutMS);
|
finished = p.state() == QProcess::NotRunning || p.waitForFinished(timeoutS * 1000);
|
||||||
hasData = false;
|
hasData = false;
|
||||||
// First check 'stdout'
|
// First check 'stdout'
|
||||||
if (p.bytesAvailable()) { // applies to readChannel() only
|
if (p.bytesAvailable()) { // applies to readChannel() only
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ struct QTCREATOR_UTILS_EXPORT SynchronousProcessResponse
|
|||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
// Helper to format an exit message.
|
// Helper to format an exit message.
|
||||||
QString exitMessage(const QString &binary, int timeoutMS) const;
|
QString exitMessage(const QString &binary, int timeoutS) const;
|
||||||
|
|
||||||
Result result;
|
Result result;
|
||||||
int exitCode;
|
int exitCode;
|
||||||
@@ -94,8 +94,8 @@ public:
|
|||||||
|
|
||||||
/* Timeout for hanging processes (triggers after no more output
|
/* Timeout for hanging processes (triggers after no more output
|
||||||
* occurs on stderr/stdout). */
|
* occurs on stderr/stdout). */
|
||||||
void setTimeout(int timeoutMS);
|
void setTimeoutS(int timeoutS);
|
||||||
int timeout() const;
|
int timeoutS() const;
|
||||||
|
|
||||||
void setCodec(QTextCodec *c);
|
void setCodec(QTextCodec *c);
|
||||||
QTextCodec *codec() const;
|
QTextCodec *codec() const;
|
||||||
@@ -136,7 +136,7 @@ public:
|
|||||||
// detection similar SynchronousProcess' handling (taking effect after no more output
|
// detection similar SynchronousProcess' handling (taking effect after no more output
|
||||||
// occurs on stderr/stdout as opposed to waitForFinished()). Returns false if a timeout
|
// occurs on stderr/stdout as opposed to waitForFinished()). Returns false if a timeout
|
||||||
// occurs. Checking of the process' exit state/code still has to be done.
|
// occurs. Checking of the process' exit state/code still has to be done.
|
||||||
static bool readDataFromProcess(QProcess &p, int timeOutMS,
|
static bool readDataFromProcess(QProcess &p, int timeoutS,
|
||||||
QByteArray *stdOut = 0, QByteArray *stdErr = 0,
|
QByteArray *stdOut = 0, QByteArray *stdErr = 0,
|
||||||
bool timeOutMessageBox = false);
|
bool timeOutMessageBox = false);
|
||||||
// Stop a process by first calling terminate() (allowing for signal handling) and
|
// Stop a process by first calling terminate() (allowing for signal handling) and
|
||||||
|
|||||||
@@ -111,7 +111,7 @@ bool PatchTool::runPatch(const QByteArray &input, const QString &workingDirector
|
|||||||
patchProcess.closeWriteChannel();
|
patchProcess.closeWriteChannel();
|
||||||
QByteArray stdOut;
|
QByteArray stdOut;
|
||||||
QByteArray stdErr;
|
QByteArray stdErr;
|
||||||
if (!Utils::SynchronousProcess::readDataFromProcess(patchProcess, 30000, &stdOut, &stdErr, true)) {
|
if (!Utils::SynchronousProcess::readDataFromProcess(patchProcess, 30, &stdOut, &stdErr, true)) {
|
||||||
Utils::SynchronousProcess::stopProcess(patchProcess);
|
Utils::SynchronousProcess::stopProcess(patchProcess);
|
||||||
MessageManager::write(QApplication::translate("Core::PatchTool", "A timeout occurred running \"%1\"").arg(patch));
|
MessageManager::write(QApplication::translate("Core::PatchTool", "A timeout occurred running \"%1\"").arg(patch));
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -991,9 +991,9 @@ static inline QString msgNotStarted(const QString &cmd)
|
|||||||
return PerforcePlugin::tr("Could not start perforce \"%1\". Please check your settings in the preferences.").arg(cmd);
|
return PerforcePlugin::tr("Could not start perforce \"%1\". Please check your settings in the preferences.").arg(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline QString msgTimeout(int timeOut)
|
static inline QString msgTimeout(int timeOutS)
|
||||||
{
|
{
|
||||||
return PerforcePlugin::tr("Perforce did not respond within timeout limit (%1 ms).").arg(timeOut );
|
return PerforcePlugin::tr("Perforce did not respond within timeout limit (%1 s).").arg(timeOutS);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline QString msgCrash()
|
static inline QString msgCrash()
|
||||||
@@ -1018,8 +1018,8 @@ PerforceResponse PerforcePlugin::synchronousProcess(const QString &workingDir,
|
|||||||
VcsOutputWindow *outputWindow = VcsOutputWindow::instance();
|
VcsOutputWindow *outputWindow = VcsOutputWindow::instance();
|
||||||
// Run, connect stderr to the output window
|
// Run, connect stderr to the output window
|
||||||
SynchronousProcess process;
|
SynchronousProcess process;
|
||||||
const int timeOut = (flags & LongTimeOut) ? settings().longTimeOutMS() : settings().timeOutMS();
|
const int timeOutS = (flags & LongTimeOut) ? settings().longTimeOutS() : settings().timeOutS();
|
||||||
process.setTimeout(timeOut);
|
process.setTimeoutS(timeOutS);
|
||||||
process.setCodec(outputCodec);
|
process.setCodec(outputCodec);
|
||||||
if (flags & OverrideDiffEnvironment)
|
if (flags & OverrideDiffEnvironment)
|
||||||
process.setProcessEnvironment(overrideDiffEnvironmentVariable());
|
process.setProcessEnvironment(overrideDiffEnvironmentVariable());
|
||||||
@@ -1116,11 +1116,11 @@ PerforceResponse PerforcePlugin::fullySynchronousProcess(const QString &workingD
|
|||||||
|
|
||||||
QByteArray stdOut;
|
QByteArray stdOut;
|
||||||
QByteArray stdErr;
|
QByteArray stdErr;
|
||||||
const int timeOut = (flags & LongTimeOut) ? settings().longTimeOutMS() : settings().timeOutMS();
|
const int timeOutS = (flags & LongTimeOut) ? settings().longTimeOutS() : settings().timeOutS();
|
||||||
if (!SynchronousProcess::readDataFromProcess(process, timeOut, &stdOut, &stdErr, true)) {
|
if (!SynchronousProcess::readDataFromProcess(process, timeOutS, &stdOut, &stdErr, true)) {
|
||||||
SynchronousProcess::stopProcess(process);
|
SynchronousProcess::stopProcess(process);
|
||||||
response.error = true;
|
response.error = true;
|
||||||
response.message = msgTimeout(timeOut);
|
response.message = msgTimeout(timeOutS);
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
if (process.exitStatus() != QProcess::NormalExit) {
|
if (process.exitStatus() != QProcess::NormalExit) {
|
||||||
|
|||||||
@@ -103,8 +103,8 @@ public:
|
|||||||
Settings settings() const;
|
Settings settings() const;
|
||||||
|
|
||||||
inline int timeOutS() const { return m_settings.timeOutS; }
|
inline int timeOutS() const { return m_settings.timeOutS; }
|
||||||
|
inline int longTimeOutS() const { return m_settings.timeOutS * 10; }
|
||||||
inline int timeOutMS() const { return m_settings.timeOutS * 1000; }
|
inline int timeOutMS() const { return m_settings.timeOutS * 1000; }
|
||||||
inline int longTimeOutMS() const { return m_settings.timeOutS * 10000; }
|
|
||||||
|
|
||||||
inline int logCount() const { return m_settings.logCount; }
|
inline int logCount() const { return m_settings.logCount; }
|
||||||
|
|
||||||
|
|||||||
@@ -932,7 +932,7 @@ SubversionResponse SubversionPlugin::runSvn(const QString &workingDir,
|
|||||||
|
|
||||||
response.error = sp_resp.result != SynchronousProcessResponse::Finished;
|
response.error = sp_resp.result != SynchronousProcessResponse::Finished;
|
||||||
if (response.error)
|
if (response.error)
|
||||||
response.message = sp_resp.exitMessage(executable.toString(), timeOutS * 1000);
|
response.message = sp_resp.exitMessage(executable.toString(), timeOutS);
|
||||||
response.stdErr = sp_resp.stdErr;
|
response.stdErr = sp_resp.stdErr;
|
||||||
response.stdOut = sp_resp.stdOut;
|
response.stdOut = sp_resp.stdOut;
|
||||||
return response;
|
return response;
|
||||||
|
|||||||
@@ -709,7 +709,7 @@ bool VcsBaseSubmitEditor::runSubmitMessageCheckScript(const QString &checkScript
|
|||||||
}
|
}
|
||||||
QByteArray stdOutData;
|
QByteArray stdOutData;
|
||||||
QByteArray stdErrData;
|
QByteArray stdErrData;
|
||||||
if (!SynchronousProcess::readDataFromProcess(checkProcess, 30000, &stdOutData, &stdErrData, false)) {
|
if (!SynchronousProcess::readDataFromProcess(checkProcess, 30, &stdOutData, &stdErrData, false)) {
|
||||||
SynchronousProcess::stopProcess(checkProcess);
|
SynchronousProcess::stopProcess(checkProcess);
|
||||||
*errorMessage = tr("The check script \"%1\" timed out.").
|
*errorMessage = tr("The check script \"%1\" timed out.").
|
||||||
arg(QDir::toNativeSeparators(checkScript));
|
arg(QDir::toNativeSeparators(checkScript));
|
||||||
|
|||||||
@@ -388,7 +388,7 @@ Utils::SynchronousProcessResponse VcsCommand::runVcs(const QStringList &argument
|
|||||||
(d->m_flags & VcsBasePlugin::ForceCLocale),
|
(d->m_flags & VcsBasePlugin::ForceCLocale),
|
||||||
d->m_sshPasswordPrompt);
|
d->m_sshPasswordPrompt);
|
||||||
process.setProcessEnvironment(env);
|
process.setProcessEnvironment(env);
|
||||||
process.setTimeout(timeoutS * 1000);
|
process.setTimeoutS(timeoutS);
|
||||||
if (d->m_codec)
|
if (d->m_codec)
|
||||||
process.setCodec(d->m_codec);
|
process.setCodec(d->m_codec);
|
||||||
|
|
||||||
@@ -470,7 +470,7 @@ Utils::SynchronousProcessResponse VcsCommand::runSynchronous(const QStringList &
|
|||||||
QByteArray stdOut;
|
QByteArray stdOut;
|
||||||
QByteArray stdErr;
|
QByteArray stdErr;
|
||||||
const bool timedOut =
|
const bool timedOut =
|
||||||
!Utils::SynchronousProcess::readDataFromProcess(*process.data(), timeoutS * 1000,
|
!Utils::SynchronousProcess::readDataFromProcess(*process.data(), timeoutS,
|
||||||
&stdOut, &stdErr, true);
|
&stdOut, &stdErr, true);
|
||||||
|
|
||||||
if (!d->m_aborted) {
|
if (!d->m_aborted) {
|
||||||
@@ -543,7 +543,7 @@ bool VcsCommand::runFullySynchronous(const QStringList &arguments, int timeoutS,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Utils::SynchronousProcess::readDataFromProcess(process, timeoutS * 1000, outputData, errorData, true)) {
|
if (!Utils::SynchronousProcess::readDataFromProcess(process, timeoutS, outputData, errorData, true)) {
|
||||||
if (errorData)
|
if (errorData)
|
||||||
errorData->append(tr("Error: Executable timed out after %1s.").arg(timeoutS).toLocal8Bit());
|
errorData->append(tr("Error: Executable timed out after %1s.").arg(timeoutS).toLocal8Bit());
|
||||||
Utils::SynchronousProcess::stopProcess(process);
|
Utils::SynchronousProcess::stopProcess(process);
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ static int testSynchronous(const QString &cmd, const QStringList &args)
|
|||||||
|
|
||||||
QByteArray stdOut;
|
QByteArray stdOut;
|
||||||
QByteArray stdErr;
|
QByteArray stdErr;
|
||||||
if (!Utils::SynchronousProcess::readDataFromProcess(p, 2000, &stdOut, &stdErr)) {
|
if (!Utils::SynchronousProcess::readDataFromProcess(p, 2, &stdOut, &stdErr)) {
|
||||||
std::fputs("Timeout", stderr);
|
std::fputs("Timeout", stderr);
|
||||||
return -3;
|
return -3;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ void MainWindow::test()
|
|||||||
const QString cmd = args.front();
|
const QString cmd = args.front();
|
||||||
args.pop_front();
|
args.pop_front();
|
||||||
Utils::SynchronousProcess process;
|
Utils::SynchronousProcess process;
|
||||||
process.setTimeout(2000);
|
process.setTimeoutS(2);
|
||||||
qDebug() << "Async: " << cmd << args;
|
qDebug() << "Async: " << cmd << args;
|
||||||
connect(&process, SIGNAL(stdOut(QString,bool)), this, SLOT(append(QString)));
|
connect(&process, SIGNAL(stdOut(QString,bool)), this, SLOT(append(QString)));
|
||||||
connect(&process, SIGNAL(stdErr(QString,bool)), this, SLOT(append(QString)));
|
connect(&process, SIGNAL(stdErr(QString,bool)), this, SLOT(append(QString)));
|
||||||
|
|||||||
Reference in New Issue
Block a user