forked from qt-creator/qt-creator
CMakeProcess: Don't use QTimer for checking the canceled state
Create a QFutureWatcher instead and connect to its canceled() signal. Replace some includes with forward declarations. Change-Id: Ie82bf8902ef8c8d87011809bd14b7db3d4f52179 Reviewed-by: <github-actions-qt-creator@cristianadam.eu> Reviewed-by: Cristian Adam <cristian.adam@qt.io>
This commit is contained in:
@@ -25,6 +25,7 @@
|
||||
|
||||
#include "cmakeprocess.h"
|
||||
|
||||
#include "builddirparameters.h"
|
||||
#include "cmakeparser.h"
|
||||
|
||||
#include <coreplugin/progressmanager/progressmanager.h>
|
||||
@@ -36,7 +37,7 @@
|
||||
#include <utils/qtcprocess.h>
|
||||
#include <utils/stringutils.h>
|
||||
|
||||
#include <QFutureInterface>
|
||||
#include <QFutureWatcher>
|
||||
|
||||
using namespace Utils;
|
||||
|
||||
@@ -52,27 +53,22 @@ static QString stripTrailingNewline(QString str)
|
||||
return str;
|
||||
}
|
||||
|
||||
CMakeProcess::CMakeProcess()
|
||||
{
|
||||
connect(&m_cancelTimer, &QTimer::timeout, this, &CMakeProcess::checkForCancelled);
|
||||
m_cancelTimer.setInterval(50);
|
||||
}
|
||||
CMakeProcess::CMakeProcess() = default;
|
||||
|
||||
CMakeProcess::~CMakeProcess()
|
||||
{
|
||||
m_process.reset();
|
||||
m_parser.flush();
|
||||
|
||||
if (m_future) {
|
||||
if (m_futureWatcher) {
|
||||
// None of the progress related functions will work after this!
|
||||
m_future->reportCanceled();
|
||||
m_future->reportFinished();
|
||||
m_futureInterface.reportCanceled();
|
||||
m_futureInterface.reportFinished();
|
||||
}
|
||||
}
|
||||
|
||||
void CMakeProcess::run(const BuildDirParameters ¶meters, const QStringList &arguments)
|
||||
{
|
||||
QTC_ASSERT(!m_process && !m_future, return);
|
||||
QTC_ASSERT(!m_process && !m_futureWatcher, return);
|
||||
|
||||
CMakeTool *cmake = parameters.cmakeTool();
|
||||
QTC_ASSERT(parameters.isValid() && cmake, return);
|
||||
@@ -109,9 +105,6 @@ void CMakeProcess::run(const BuildDirParameters ¶meters, const QStringList &
|
||||
// then we are racing against CMakeCache.txt also getting deleted.
|
||||
|
||||
m_process.reset(new QtcProcess);
|
||||
m_processWasCanceled = false;
|
||||
|
||||
m_cancelTimer.start();
|
||||
|
||||
m_process->setWorkingDirectory(buildDirectory);
|
||||
m_process->setEnvironment(parameters.environment);
|
||||
@@ -136,14 +129,17 @@ void CMakeProcess::run(const BuildDirParameters ¶meters, const QStringList &
|
||||
TaskHub::clearTasks(ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM);
|
||||
|
||||
BuildSystem::startNewBuildSystemOutput(
|
||||
tr("Running %1 in %2.").arg(commandLine.toUserOutput()).arg(buildDirectory.toUserOutput()));
|
||||
tr("Running %1 in %2.").arg(commandLine.toUserOutput(), buildDirectory.toUserOutput()));
|
||||
|
||||
m_future.reset(new QFutureInterface<void>);
|
||||
m_future->setProgressRange(0, 1);
|
||||
Core::ProgressManager::addTimedTask(*m_future.get(),
|
||||
m_futureInterface = QFutureInterface<void>();
|
||||
m_futureInterface.setProgressRange(0, 1);
|
||||
Core::ProgressManager::addTimedTask(m_futureInterface,
|
||||
tr("Configuring \"%1\"").arg(parameters.projectName),
|
||||
"CMake.Configure",
|
||||
10);
|
||||
m_futureWatcher.reset(new QFutureWatcher<void>);
|
||||
connect(m_futureWatcher.get(), &QFutureWatcher<void>::canceled, this, &CMakeProcess::stop);
|
||||
m_futureWatcher->setFuture(m_futureInterface.future());
|
||||
|
||||
m_process->setCommand(commandLine);
|
||||
emit started();
|
||||
@@ -153,26 +149,22 @@ void CMakeProcess::run(const BuildDirParameters ¶meters, const QStringList &
|
||||
|
||||
void CMakeProcess::stop()
|
||||
{
|
||||
if (m_process) {
|
||||
m_processWasCanceled = true;
|
||||
m_process->close();
|
||||
handleProcessDone({15, QProcess::CrashExit, QProcess::Crashed, {}});
|
||||
}
|
||||
if (!m_process)
|
||||
return;
|
||||
m_process->close();
|
||||
m_futureWatcher->disconnect();
|
||||
handleProcessDone({15, QProcess::CrashExit, QProcess::Crashed, {}});
|
||||
}
|
||||
|
||||
void CMakeProcess::handleProcessDone(const Utils::ProcessResultData &resultData)
|
||||
{
|
||||
QTC_ASSERT(m_future, return);
|
||||
|
||||
m_cancelTimer.stop();
|
||||
|
||||
const int code = resultData.m_exitCode;
|
||||
|
||||
QString msg;
|
||||
if (resultData.m_error == QProcess::FailedToStart) {
|
||||
msg = tr("CMake process failed to start.");
|
||||
} else if (resultData.m_exitStatus != QProcess::NormalExit) {
|
||||
if (m_processWasCanceled)
|
||||
if (m_futureInterface.isCanceled())
|
||||
msg = tr("CMake process was canceled by the user.");
|
||||
else
|
||||
msg = tr("CMake process crashed.");
|
||||
@@ -184,12 +176,12 @@ void CMakeProcess::handleProcessDone(const Utils::ProcessResultData &resultData)
|
||||
if (!msg.isEmpty()) {
|
||||
BuildSystem::appendBuildSystemOutput(msg + '\n');
|
||||
TaskHub::addTask(BuildSystemTask(Task::Error, msg));
|
||||
m_future->reportCanceled();
|
||||
m_futureInterface.reportCanceled();
|
||||
} else {
|
||||
m_future->setProgressValue(1);
|
||||
m_futureInterface.setProgressValue(1);
|
||||
}
|
||||
|
||||
m_future->reportFinished();
|
||||
m_futureInterface.reportFinished();
|
||||
|
||||
emit finished();
|
||||
|
||||
@@ -197,16 +189,5 @@ void CMakeProcess::handleProcessDone(const Utils::ProcessResultData &resultData)
|
||||
BuildSystem::appendBuildSystemOutput(elapsedTime + '\n');
|
||||
}
|
||||
|
||||
void CMakeProcess::checkForCancelled()
|
||||
{
|
||||
if (!m_process || !m_future)
|
||||
return;
|
||||
|
||||
if (m_future->isCanceled()) {
|
||||
m_cancelTimer.stop();
|
||||
stop();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace CMakeProjectManager
|
||||
|
@@ -25,20 +25,18 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "builddirparameters.h"
|
||||
|
||||
#include <utils/outputformatter.h>
|
||||
|
||||
#include <QElapsedTimer>
|
||||
#include <QFutureInterface>
|
||||
#include <QObject>
|
||||
#include <QStringList>
|
||||
#include <QTimer>
|
||||
|
||||
#include <memory>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
template<class T>
|
||||
class QFutureInterface;
|
||||
class QFutureWatcher;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
namespace Utils {
|
||||
@@ -49,6 +47,8 @@ class QtcProcess;
|
||||
namespace CMakeProjectManager {
|
||||
namespace Internal {
|
||||
|
||||
class BuildDirParameters;
|
||||
|
||||
class CMakeProcess : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
@@ -68,13 +68,11 @@ signals:
|
||||
|
||||
private:
|
||||
void handleProcessDone(const Utils::ProcessResultData &resultData);
|
||||
void checkForCancelled();
|
||||
|
||||
std::unique_ptr<Utils::QtcProcess> m_process;
|
||||
Utils::OutputFormatter m_parser;
|
||||
std::unique_ptr<QFutureInterface<void>> m_future;
|
||||
bool m_processWasCanceled = false;
|
||||
QTimer m_cancelTimer;
|
||||
QFutureInterface<void> m_futureInterface;
|
||||
std::unique_ptr<QFutureWatcher<void>> m_futureWatcher;
|
||||
QElapsedTimer m_elapsed;
|
||||
int m_lastExitCode = 0;
|
||||
};
|
||||
|
@@ -25,6 +25,7 @@
|
||||
|
||||
#include "fileapireader.h"
|
||||
|
||||
#include "cmakeprocess.h"
|
||||
#include "fileapidataextractor.h"
|
||||
#include "fileapiparser.h"
|
||||
|
||||
|
@@ -25,8 +25,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "builddirparameters.h"
|
||||
#include "cmakebuildtarget.h"
|
||||
#include "cmakeprocess.h"
|
||||
#include "cmakeprojectnodes.h"
|
||||
#include "fileapidataextractor.h"
|
||||
|
||||
@@ -49,6 +49,7 @@ class ProjectNode;
|
||||
namespace CMakeProjectManager {
|
||||
namespace Internal {
|
||||
|
||||
class CMakeProcess;
|
||||
class FileApiQtcData;
|
||||
|
||||
class FileApiReader final : public QObject
|
||||
|
Reference in New Issue
Block a user