From 97392daaf35096af6691f5997bc7171729b06759 Mon Sep 17 00:00:00 2001 From: Tobias Hunger Date: Fri, 14 Jun 2019 16:42:41 +0200 Subject: [PATCH] CMake: Allow cancellation of CMake process Allow cancellation of cmake runs in tea-leaf and fileapi modes. At least in those modes cmake can now get stopped when it goes into an infinite loop. Change-Id: I4e9bd769292325b9837904cd391ff61dbc477898 Reviewed-by: Eike Ziller --- .../cmakeprojectmanager/cmakeprocess.cpp | 37 ++++++++++++++++--- .../cmakeprojectmanager/cmakeprocess.h | 4 ++ 2 files changed, 36 insertions(+), 5 deletions(-) diff --git a/src/plugins/cmakeprojectmanager/cmakeprocess.cpp b/src/plugins/cmakeprojectmanager/cmakeprocess.cpp index 9e54b15c026..cd6a3d626a6 100644 --- a/src/plugins/cmakeprojectmanager/cmakeprocess.cpp +++ b/src/plugins/cmakeprojectmanager/cmakeprocess.cpp @@ -38,6 +38,7 @@ #include #include +#include namespace CMakeProjectManager { namespace Internal { @@ -57,8 +58,11 @@ static QString lineSplit(const QString &rest, const QByteArray &array, std::func return tmp.mid(start); } - -CMakeProcess::CMakeProcess() = default; +CMakeProcess::CMakeProcess() +{ + connect(&m_cancelTimer, &QTimer::timeout, this, &CMakeProcess::checkForCancelled); + m_cancelTimer.setInterval(500); +} CMakeProcess::~CMakeProcess() { @@ -116,6 +120,10 @@ void CMakeProcess::run(const BuildDirParameters ¶meters, const QStringList & // then we are racing against CMakeCache.txt also getting deleted. auto process = std::make_unique(); + m_processWasCanceled = false; + + m_cancelTimer.start(); + process->setWorkingDirectory(workDirectory.toString()); process->setEnvironment(parameters.environment); @@ -204,14 +212,21 @@ void CMakeProcess::handleProcessFinished(int code, QProcess::ExitStatus status) { QTC_ASSERT(m_process && m_future, return); + m_cancelTimer.stop(); + processStandardOutput(); processStandardError(); QString msg; - if (status != QProcess::NormalExit) - msg = tr("*** cmake process crashed."); - else if (code != 0) + if (status != QProcess::NormalExit) { + if (m_processWasCanceled) { + msg = tr("*** cmake process was canceled by the user."); + } else { + msg = tr("*** cmake process crashed."); + } + } else if (code != 0) { msg = tr("*** cmake process exited with exit code %1.").arg(code); + } if (!msg.isEmpty()) { Core::MessageManager::write(msg); @@ -226,5 +241,17 @@ void CMakeProcess::handleProcessFinished(int code, QProcess::ExitStatus status) emit finished(code, status); } +void CMakeProcess::checkForCancelled() +{ + if (!m_process || !m_future) + return; + + if (m_future->isCanceled()) { + m_cancelTimer.stop(); + m_processWasCanceled = true; + m_process->close(); + } +} + } // namespace Internal } // namespace CMakeProjectManager diff --git a/src/plugins/cmakeprojectmanager/cmakeprocess.h b/src/plugins/cmakeprojectmanager/cmakeprocess.h index 579a235d237..9675822435a 100644 --- a/src/plugins/cmakeprojectmanager/cmakeprocess.h +++ b/src/plugins/cmakeprojectmanager/cmakeprocess.h @@ -32,6 +32,7 @@ #include #include +#include #include @@ -67,10 +68,13 @@ signals: private: void handleProcessFinished(int code, QProcess::ExitStatus status); + void checkForCancelled(); std::unique_ptr m_process; std::unique_ptr m_parser; std::unique_ptr> m_future; + bool m_processWasCanceled = false; + QTimer m_cancelTimer; }; } // namespace Internal