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 "cmakeprocess.h"
|
||||||
|
|
||||||
|
#include "builddirparameters.h"
|
||||||
#include "cmakeparser.h"
|
#include "cmakeparser.h"
|
||||||
|
|
||||||
#include <coreplugin/progressmanager/progressmanager.h>
|
#include <coreplugin/progressmanager/progressmanager.h>
|
||||||
@@ -36,7 +37,7 @@
|
|||||||
#include <utils/qtcprocess.h>
|
#include <utils/qtcprocess.h>
|
||||||
#include <utils/stringutils.h>
|
#include <utils/stringutils.h>
|
||||||
|
|
||||||
#include <QFutureInterface>
|
#include <QFutureWatcher>
|
||||||
|
|
||||||
using namespace Utils;
|
using namespace Utils;
|
||||||
|
|
||||||
@@ -52,27 +53,22 @@ static QString stripTrailingNewline(QString str)
|
|||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
CMakeProcess::CMakeProcess()
|
CMakeProcess::CMakeProcess() = default;
|
||||||
{
|
|
||||||
connect(&m_cancelTimer, &QTimer::timeout, this, &CMakeProcess::checkForCancelled);
|
|
||||||
m_cancelTimer.setInterval(50);
|
|
||||||
}
|
|
||||||
|
|
||||||
CMakeProcess::~CMakeProcess()
|
CMakeProcess::~CMakeProcess()
|
||||||
{
|
{
|
||||||
m_process.reset();
|
|
||||||
m_parser.flush();
|
m_parser.flush();
|
||||||
|
|
||||||
if (m_future) {
|
if (m_futureWatcher) {
|
||||||
// None of the progress related functions will work after this!
|
// None of the progress related functions will work after this!
|
||||||
m_future->reportCanceled();
|
m_futureInterface.reportCanceled();
|
||||||
m_future->reportFinished();
|
m_futureInterface.reportFinished();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMakeProcess::run(const BuildDirParameters ¶meters, const QStringList &arguments)
|
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();
|
CMakeTool *cmake = parameters.cmakeTool();
|
||||||
QTC_ASSERT(parameters.isValid() && cmake, return);
|
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.
|
// then we are racing against CMakeCache.txt also getting deleted.
|
||||||
|
|
||||||
m_process.reset(new QtcProcess);
|
m_process.reset(new QtcProcess);
|
||||||
m_processWasCanceled = false;
|
|
||||||
|
|
||||||
m_cancelTimer.start();
|
|
||||||
|
|
||||||
m_process->setWorkingDirectory(buildDirectory);
|
m_process->setWorkingDirectory(buildDirectory);
|
||||||
m_process->setEnvironment(parameters.environment);
|
m_process->setEnvironment(parameters.environment);
|
||||||
@@ -136,14 +129,17 @@ void CMakeProcess::run(const BuildDirParameters ¶meters, const QStringList &
|
|||||||
TaskHub::clearTasks(ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM);
|
TaskHub::clearTasks(ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM);
|
||||||
|
|
||||||
BuildSystem::startNewBuildSystemOutput(
|
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_futureInterface = QFutureInterface<void>();
|
||||||
m_future->setProgressRange(0, 1);
|
m_futureInterface.setProgressRange(0, 1);
|
||||||
Core::ProgressManager::addTimedTask(*m_future.get(),
|
Core::ProgressManager::addTimedTask(m_futureInterface,
|
||||||
tr("Configuring \"%1\"").arg(parameters.projectName),
|
tr("Configuring \"%1\"").arg(parameters.projectName),
|
||||||
"CMake.Configure",
|
"CMake.Configure",
|
||||||
10);
|
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);
|
m_process->setCommand(commandLine);
|
||||||
emit started();
|
emit started();
|
||||||
@@ -153,26 +149,22 @@ void CMakeProcess::run(const BuildDirParameters ¶meters, const QStringList &
|
|||||||
|
|
||||||
void CMakeProcess::stop()
|
void CMakeProcess::stop()
|
||||||
{
|
{
|
||||||
if (m_process) {
|
if (!m_process)
|
||||||
m_processWasCanceled = true;
|
return;
|
||||||
m_process->close();
|
m_process->close();
|
||||||
|
m_futureWatcher->disconnect();
|
||||||
handleProcessDone({15, QProcess::CrashExit, QProcess::Crashed, {}});
|
handleProcessDone({15, QProcess::CrashExit, QProcess::Crashed, {}});
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMakeProcess::handleProcessDone(const Utils::ProcessResultData &resultData)
|
void CMakeProcess::handleProcessDone(const Utils::ProcessResultData &resultData)
|
||||||
{
|
{
|
||||||
QTC_ASSERT(m_future, return);
|
|
||||||
|
|
||||||
m_cancelTimer.stop();
|
|
||||||
|
|
||||||
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_processWasCanceled)
|
if (m_futureInterface.isCanceled())
|
||||||
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.");
|
||||||
@@ -184,12 +176,12 @@ void CMakeProcess::handleProcessDone(const Utils::ProcessResultData &resultData)
|
|||||||
if (!msg.isEmpty()) {
|
if (!msg.isEmpty()) {
|
||||||
BuildSystem::appendBuildSystemOutput(msg + '\n');
|
BuildSystem::appendBuildSystemOutput(msg + '\n');
|
||||||
TaskHub::addTask(BuildSystemTask(Task::Error, msg));
|
TaskHub::addTask(BuildSystemTask(Task::Error, msg));
|
||||||
m_future->reportCanceled();
|
m_futureInterface.reportCanceled();
|
||||||
} else {
|
} else {
|
||||||
m_future->setProgressValue(1);
|
m_futureInterface.setProgressValue(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_future->reportFinished();
|
m_futureInterface.reportFinished();
|
||||||
|
|
||||||
emit finished();
|
emit finished();
|
||||||
|
|
||||||
@@ -197,16 +189,5 @@ void CMakeProcess::handleProcessDone(const Utils::ProcessResultData &resultData)
|
|||||||
BuildSystem::appendBuildSystemOutput(elapsedTime + '\n');
|
BuildSystem::appendBuildSystemOutput(elapsedTime + '\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMakeProcess::checkForCancelled()
|
|
||||||
{
|
|
||||||
if (!m_process || !m_future)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (m_future->isCanceled()) {
|
|
||||||
m_cancelTimer.stop();
|
|
||||||
stop();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
} // namespace CMakeProjectManager
|
} // namespace CMakeProjectManager
|
||||||
|
@@ -25,20 +25,18 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "builddirparameters.h"
|
|
||||||
|
|
||||||
#include <utils/outputformatter.h>
|
#include <utils/outputformatter.h>
|
||||||
|
|
||||||
#include <QElapsedTimer>
|
#include <QElapsedTimer>
|
||||||
|
#include <QFutureInterface>
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
#include <QTimer>
|
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
template<class T>
|
template<class T>
|
||||||
class QFutureInterface;
|
class QFutureWatcher;
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
namespace Utils {
|
namespace Utils {
|
||||||
@@ -49,6 +47,8 @@ class QtcProcess;
|
|||||||
namespace CMakeProjectManager {
|
namespace CMakeProjectManager {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
|
class BuildDirParameters;
|
||||||
|
|
||||||
class CMakeProcess : public QObject
|
class CMakeProcess : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@@ -68,13 +68,11 @@ signals:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void handleProcessDone(const Utils::ProcessResultData &resultData);
|
void handleProcessDone(const Utils::ProcessResultData &resultData);
|
||||||
void checkForCancelled();
|
|
||||||
|
|
||||||
std::unique_ptr<Utils::QtcProcess> m_process;
|
std::unique_ptr<Utils::QtcProcess> m_process;
|
||||||
Utils::OutputFormatter m_parser;
|
Utils::OutputFormatter m_parser;
|
||||||
std::unique_ptr<QFutureInterface<void>> m_future;
|
QFutureInterface<void> m_futureInterface;
|
||||||
bool m_processWasCanceled = false;
|
std::unique_ptr<QFutureWatcher<void>> m_futureWatcher;
|
||||||
QTimer m_cancelTimer;
|
|
||||||
QElapsedTimer m_elapsed;
|
QElapsedTimer m_elapsed;
|
||||||
int m_lastExitCode = 0;
|
int m_lastExitCode = 0;
|
||||||
};
|
};
|
||||||
|
@@ -25,6 +25,7 @@
|
|||||||
|
|
||||||
#include "fileapireader.h"
|
#include "fileapireader.h"
|
||||||
|
|
||||||
|
#include "cmakeprocess.h"
|
||||||
#include "fileapidataextractor.h"
|
#include "fileapidataextractor.h"
|
||||||
#include "fileapiparser.h"
|
#include "fileapiparser.h"
|
||||||
|
|
||||||
|
@@ -25,8 +25,8 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "builddirparameters.h"
|
||||||
#include "cmakebuildtarget.h"
|
#include "cmakebuildtarget.h"
|
||||||
#include "cmakeprocess.h"
|
|
||||||
#include "cmakeprojectnodes.h"
|
#include "cmakeprojectnodes.h"
|
||||||
#include "fileapidataextractor.h"
|
#include "fileapidataextractor.h"
|
||||||
|
|
||||||
@@ -49,6 +49,7 @@ class ProjectNode;
|
|||||||
namespace CMakeProjectManager {
|
namespace CMakeProjectManager {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
|
class CMakeProcess;
|
||||||
class FileApiQtcData;
|
class FileApiQtcData;
|
||||||
|
|
||||||
class FileApiReader final : public QObject
|
class FileApiReader final : public QObject
|
||||||
|
Reference in New Issue
Block a user