From 214679d65ba4ebd2d2be0b177f5eeac7df6d32aa Mon Sep 17 00:00:00 2001 From: Friedemann Kleint <Friedemann.Kleint@nokia.com> Date: Fri, 26 Feb 2010 17:43:37 +0100 Subject: [PATCH] Git: Improve Timeouts. - Observe timeout setting when running synchronous commands. - Increase Default on Windows - Stop process with terminate first (signal). Task-number: QTCREATORBUG-777 --- src/plugins/git/gitclient.cpp | 14 +++++++------- src/plugins/git/gitcommand.cpp | 23 ++++++++++++++++++++--- src/plugins/git/gitcommand.h | 8 ++++++++ src/plugins/git/gitsettings.cpp | 17 ++++++++++++----- src/plugins/git/gitsettings.h | 2 +- src/plugins/git/settingspage.cpp | 4 ++-- 6 files changed, 50 insertions(+), 18 deletions(-) diff --git a/src/plugins/git/gitclient.cpp b/src/plugins/git/gitclient.cpp index 5026295e151..c7a150a2ef4 100644 --- a/src/plugins/git/gitclient.cpp +++ b/src/plugins/git/gitclient.cpp @@ -236,20 +236,20 @@ void GitClient::diff(const QString &workingDirectory, QStringList arguments(commonDiffArgs); arguments << diffArgs; VCSBase::VCSBaseOutputWindow::instance()->appendCommand(formatCommand(binary, arguments)); - command->addJob(arguments, m_settings.timeout); + command->addJob(arguments, m_settings.timeoutSeconds); } else { // Files diff. if (!unstagedFileNames.empty()) { QStringList arguments(commonDiffArgs); arguments << QLatin1String("--") << unstagedFileNames; VCSBase::VCSBaseOutputWindow::instance()->appendCommand(formatCommand(binary, arguments)); - command->addJob(arguments, m_settings.timeout); + command->addJob(arguments, m_settings.timeoutSeconds); } if (!stagedFileNames.empty()) { QStringList arguments(commonDiffArgs); arguments << QLatin1String("--cached") << diffArgs << QLatin1String("--") << stagedFileNames; VCSBase::VCSBaseOutputWindow::instance()->appendCommand(formatCommand(binary, arguments)); - command->addJob(arguments, m_settings.timeout); + command->addJob(arguments, m_settings.timeoutSeconds); } } command->execute(); @@ -985,7 +985,7 @@ GitCommand *GitClient::executeGit(const QString &workingDirectory, { VCSBase::VCSBaseOutputWindow::instance()->appendCommand(formatCommand(QLatin1String(Constants::GIT_BINARY), arguments)); GitCommand *command = createCommand(workingDirectory, editor, outputToWindow, editorLineNumber); - command->addJob(arguments, m_settings.timeout); + command->addJob(arguments, m_settings.timeoutSeconds); command->setTerminationReportMode(tm); command->execute(); return command; @@ -1042,10 +1042,10 @@ bool GitClient::synchronousGit(const QString &workingDirectory, return false; } - if (!process.waitForFinished()) { + if (!process.waitForFinished(m_settings.timeoutSeconds * 1000)) { if (errorText) - *errorText = "Error: Git timed out."; - process.kill(); + *errorText = GitCommand::msgTimeout(m_settings.timeoutSeconds).toLocal8Bit(); + GitCommand::stopProcess(process); return false; } diff --git a/src/plugins/git/gitcommand.cpp b/src/plugins/git/gitcommand.cpp index fed9d81b671..e1f4ac3a948 100644 --- a/src/plugins/git/gitcommand.cpp +++ b/src/plugins/git/gitcommand.cpp @@ -112,6 +112,22 @@ void GitCommand::execute() QLatin1String("Git.action")); } +QString GitCommand::msgTimeout(int seconds) +{ + return tr("Error: Git timed out after %1s.").arg(seconds); +} + +bool GitCommand::stopProcess(QProcess &p) +{ + if (p.state() != QProcess::Running) + return true; + p.terminate(); + if (p.waitForFinished(300)) + return true; + p.kill(); + return p.waitForFinished(300); +} + void GitCommand::run() { if (Git::Constants::debug) @@ -139,10 +155,11 @@ void GitCommand::run() } process.closeWriteChannel(); - if (!process.waitForFinished(m_jobs.at(j).timeout * 1000)) { - process.terminate(); + const int timeOutSeconds = m_jobs.at(j).timeout; + if (!process.waitForFinished(timeOutSeconds * 1000)) { + stopProcess(process); ok = false; - error += QLatin1String("Error: Git timed out"); + error += msgTimeout(timeOutSeconds); break; } diff --git a/src/plugins/git/gitcommand.h b/src/plugins/git/gitcommand.h index 8f1c5aad0ec..9345ea4d3f1 100644 --- a/src/plugins/git/gitcommand.h +++ b/src/plugins/git/gitcommand.h @@ -34,6 +34,10 @@ #include <QtCore/QStringList> #include <QtCore/QVariant> +QT_BEGIN_NAMESPACE +class QProcess; +QT_END_NAMESPACE + namespace Git { namespace Internal { @@ -66,6 +70,10 @@ public: TerminationReportMode reportTerminationMode() const; void setTerminationReportMode(TerminationReportMode m); + static QString msgTimeout(int seconds); + // Helper to kill a process by SIGNAL first, allowing for cleanup + static bool stopProcess(QProcess &p); + private: void run(); diff --git a/src/plugins/git/gitsettings.cpp b/src/plugins/git/gitsettings.cpp index 13277d225d2..8c7a87a6afe 100644 --- a/src/plugins/git/gitsettings.cpp +++ b/src/plugins/git/gitsettings.cpp @@ -45,7 +45,14 @@ static const char *promptToSubmitKeyC = "PromptForSubmit"; static const char *omitAnnotationDateKeyC = "OmitAnnotationDate"; static const char *spaceIgnorantBlameKeyC = "SpaceIgnorantBlame"; -enum { defaultLogCount = 100 , defaultTimeOut = 30}; +enum { + defaultLogCount = 100 , +#ifdef Q_OS_WIN + defaultTimeOut = 60 +#else + defaultTimeOut = 30 +#endif +}; namespace Git { namespace Internal { @@ -53,7 +60,7 @@ namespace Internal { GitSettings::GitSettings() : adoptPath(false), logCount(defaultLogCount), - timeout(defaultTimeOut), + timeoutSeconds(defaultTimeOut), promptToSubmit(true), omitAnnotationDate(false), spaceIgnorantBlame(true) @@ -66,7 +73,7 @@ void GitSettings::fromSettings(QSettings *settings) adoptPath = settings->value(QLatin1String(sysEnvKeyC), false).toBool(); path = settings->value(QLatin1String(pathKeyC), QString()).toString(); logCount = settings->value(QLatin1String(logCountKeyC), defaultLogCount).toInt(); - timeout = settings->value(QLatin1String(timeoutKeyC), defaultTimeOut).toInt(); + timeoutSeconds = settings->value(QLatin1String(timeoutKeyC), defaultTimeOut).toInt(); promptToSubmit = settings->value(QLatin1String(promptToSubmitKeyC), true).toBool(); omitAnnotationDate = settings->value(QLatin1String(omitAnnotationDateKeyC), false).toBool(); spaceIgnorantBlame = settings->value(QLatin1String(spaceIgnorantBlameKeyC), true).toBool(); @@ -79,7 +86,7 @@ void GitSettings::toSettings(QSettings *settings) const settings->setValue(QLatin1String(sysEnvKeyC), adoptPath); settings->setValue(QLatin1String(pathKeyC), path); settings->setValue(QLatin1String(logCountKeyC), logCount); - settings->setValue(QLatin1String(timeoutKeyC), timeout); + settings->setValue(QLatin1String(timeoutKeyC), timeoutSeconds); settings->setValue(QLatin1String(promptToSubmitKeyC), promptToSubmit); settings->setValue(QLatin1String(omitAnnotationDateKeyC), omitAnnotationDate); settings->setValue(QLatin1String(spaceIgnorantBlameKeyC), spaceIgnorantBlame); @@ -89,7 +96,7 @@ void GitSettings::toSettings(QSettings *settings) const bool GitSettings::equals(const GitSettings &s) const { return adoptPath == s.adoptPath && path == s.path && logCount == s.logCount - && timeout == s.timeout && promptToSubmit == s.promptToSubmit + && timeoutSeconds == s.timeoutSeconds && promptToSubmit == s.promptToSubmit && omitAnnotationDate == s.omitAnnotationDate && spaceIgnorantBlame == s.spaceIgnorantBlame; } diff --git a/src/plugins/git/gitsettings.h b/src/plugins/git/gitsettings.h index e1ca964b8a4..ef0b46c21f7 100644 --- a/src/plugins/git/gitsettings.h +++ b/src/plugins/git/gitsettings.h @@ -54,7 +54,7 @@ struct GitSettings bool adoptPath; QString path; int logCount; - int timeout; + int timeoutSeconds; bool promptToSubmit; bool omitAnnotationDate; bool spaceIgnorantBlame; diff --git a/src/plugins/git/settingspage.cpp b/src/plugins/git/settingspage.cpp index 61abe4148e5..f9157d7de27 100644 --- a/src/plugins/git/settingspage.cpp +++ b/src/plugins/git/settingspage.cpp @@ -55,7 +55,7 @@ GitSettings SettingsPageWidget::settings() const rc.path = m_ui.pathLineEdit->text(); rc.adoptPath = m_ui.environmentGroupBox->isChecked() && !rc.path.isEmpty(); rc.logCount = m_ui.logCountSpinBox->value(); - rc.timeout = m_ui.timeoutSpinBox->value(); + rc.timeoutSeconds = m_ui.timeoutSpinBox->value(); rc.promptToSubmit = m_ui.promptToSubmitCheckBox->isChecked(); rc.omitAnnotationDate = m_ui.omitAnnotationDataCheckBox->isChecked(); rc.spaceIgnorantBlame = m_ui.spaceIgnorantBlameCheckBox->isChecked(); @@ -67,7 +67,7 @@ void SettingsPageWidget::setSettings(const GitSettings &s) m_ui.environmentGroupBox->setChecked(s.adoptPath); m_ui.pathLineEdit->setText(s.path); m_ui.logCountSpinBox->setValue(s.logCount); - m_ui.timeoutSpinBox->setValue(s.timeout); + m_ui.timeoutSpinBox->setValue(s.timeoutSeconds); m_ui.promptToSubmitCheckBox->setChecked(s.promptToSubmit); m_ui.omitAnnotationDataCheckBox->setChecked(s.omitAnnotationDate); m_ui.spaceIgnorantBlameCheckBox->setChecked(s.spaceIgnorantBlame); -- GitLab