CMakeProcess: Delete the watcher prior to finishing the future

Delete the watcher from the handleProcessDone() handler
in order to avoid a circular call to the handler in case the
handler canceled the task.

Delete the watcher also from destructor, prior to canceling
the task.

Fixes: QTCREATORBUG-27564
Change-Id: Ic5859ea159f66106602ed1bf1fc32e439edf28d9
Reviewed-by: Cristian Adam <cristian.adam@qt.io>
This commit is contained in:
Jarek Kobus
2022-05-18 21:13:48 +02:00
parent 64fc40c3a5
commit f58a25b60a

View File

@@ -45,6 +45,7 @@ namespace CMakeProjectManager {
namespace Internal { namespace Internal {
using namespace ProjectExplorer; using namespace ProjectExplorer;
const int USER_STOP_EXIT_CODE = 15;
static QString stripTrailingNewline(QString str) static QString stripTrailingNewline(QString str)
{ {
@@ -60,6 +61,7 @@ CMakeProcess::~CMakeProcess()
m_parser.flush(); m_parser.flush();
if (m_futureWatcher) { if (m_futureWatcher) {
m_futureWatcher.reset();
// None of the progress related functions will work after this! // None of the progress related functions will work after this!
m_futureInterface.reportCanceled(); m_futureInterface.reportCanceled();
m_futureInterface.reportFinished(); m_futureInterface.reportFinished();
@@ -68,7 +70,7 @@ CMakeProcess::~CMakeProcess()
void CMakeProcess::run(const BuildDirParameters &parameters, const QStringList &arguments) void CMakeProcess::run(const BuildDirParameters &parameters, const QStringList &arguments)
{ {
QTC_ASSERT(!m_process && !m_futureWatcher, return); QTC_ASSERT(!m_process, return);
CMakeTool *cmake = parameters.cmakeTool(); CMakeTool *cmake = parameters.cmakeTool();
QTC_ASSERT(parameters.isValid() && cmake, return); QTC_ASSERT(parameters.isValid() && cmake, return);
@@ -152,19 +154,22 @@ void CMakeProcess::stop()
if (!m_process) if (!m_process)
return; return;
m_process->close(); m_process->close();
m_futureWatcher->disconnect(); handleProcessDone({USER_STOP_EXIT_CODE, QProcess::CrashExit, QProcess::Crashed, {}});
handleProcessDone({15, QProcess::CrashExit, QProcess::Crashed, {}});
} }
void CMakeProcess::handleProcessDone(const Utils::ProcessResultData &resultData) void CMakeProcess::handleProcessDone(const Utils::ProcessResultData &resultData)
{ {
if (m_futureWatcher) {
m_futureWatcher->disconnect();
m_futureWatcher.release()->deleteLater();
}
const int code = resultData.m_exitCode; const int code = resultData.m_exitCode;
QString msg; QString msg;
if (resultData.m_error == QProcess::FailedToStart) { if (resultData.m_error == QProcess::FailedToStart) {
msg = tr("CMake process failed to start."); msg = tr("CMake process failed to start.");
} else if (resultData.m_exitStatus != QProcess::NormalExit) { } else if (resultData.m_exitStatus != QProcess::NormalExit) {
if (m_futureInterface.isCanceled()) if (m_futureInterface.isCanceled() || code == USER_STOP_EXIT_CODE)
msg = tr("CMake process was canceled by the user."); msg = tr("CMake process was canceled by the user.");
else else
msg = tr("CMake process crashed."); msg = tr("CMake process crashed.");