(Re-)Start replacing ApplicationLauncher in SimpleTargetRunner

This is a second attempt, as just replacing with QtcProcess lost
functionality. Try again with baby steps.

This here effectively reverts commit b05fc053ef
and starts with pimpl'ing SimpleTargetRunner instead. Plan is to
follow-up with dissolving the ApplicationLauncher in the pimpl,
combine combinable pieces, and finally clean up. Ideally, not much
more that a slightly customized QtcProcess should be left.

Change-Id: I69e7b01588259fe60bb76ef1ba741a183322c4de
Reviewed-by: Jarek Kobus <jaroslaw.kobus@qt.io>
This commit is contained in:
hjk
2022-05-23 11:01:05 +02:00
parent f4b7faff18
commit 21d0175dab
2 changed files with 47 additions and 46 deletions

View File

@@ -25,6 +25,7 @@
#include "runcontrol.h"
#include "applicationlauncher.h"
#include "devicesupport/desktopdevice.h"
#include "devicesupport/idevice.h"
#include "abi.h"
@@ -1189,16 +1190,33 @@ void RunControlPrivate::debugMessage(const QString &msg)
// SimpleTargetRunner
namespace Internal {
class SimpleTargetRunnerPrivate
{
public:
ApplicationLauncher m_launcher;
std::function<void()> m_starter;
bool m_stopReported = false;
bool m_stopForced = false;
};
} // Internal
SimpleTargetRunner::SimpleTargetRunner(RunControl *runControl)
: RunWorker(runControl)
: RunWorker(runControl), d(new Internal::SimpleTargetRunnerPrivate)
{
setId("SimpleTargetRunner");
}
SimpleTargetRunner::~SimpleTargetRunner() = default;
void SimpleTargetRunner::start()
{
if (m_starter) {
m_starter();
if (d->m_starter) {
d->m_starter();
} else {
Runnable runnable = runControl()->runnable();
runnable.device = runControl()->device();
@@ -1216,55 +1234,40 @@ void SimpleTargetRunner::doStart(const Runnable &runnable)
if (auto runAsRootAspect = runControl()->aspect<RunAsRootAspect>())
runAsRoot = runAsRootAspect->value;
Environment env = runnable.environment;
if (runAsRoot)
RunControl::provideAskPassEntry(env);
m_stopForced = false;
m_stopReported = false;
m_launcher.disconnect(this);
m_launcher.setTerminalMode(useTerminal ? TerminalMode::On : TerminalMode::Off);
m_launcher.setRunAsRoot(runAsRoot);
m_launcher.setCommand(runnable.command);
m_launcher.setWorkingDirectory(runnable.workingDirectory);
m_launcher.setEnvironment(env);
m_launcher.setExtraData(runnable.extraData);
d->m_stopForced = false;
d->m_stopReported = false;
d->m_launcher.disconnect(this);
d->m_launcher.setUseTerminal(useTerminal);
d->m_launcher.setRunAsRoot(runAsRoot);
const QString msg = RunControl::tr("Starting %1...").arg(runnable.command.toUserOutput());
appendMessage(msg, Utils::NormalMessageFormat);
connect(&m_launcher, &QtcProcess::done, this, [this, runnable] {
if (m_stopReported)
connect(&d->m_launcher, &ApplicationLauncher::done, this, [this, runnable] {
if (d->m_stopReported)
return;
const QString executable = runnable.command.executable().toUserOutput();
const ProcessResultData resultData = m_launcher.resultData();
const ProcessResultData resultData = d->m_launcher.resultData();
QString msg = tr("%2 exited with code %1").arg(resultData.m_exitCode).arg(executable);
if (resultData.m_exitStatus == QProcess::CrashExit)
msg = tr("%1 crashed.").arg(executable);
else if (m_stopForced)
else if (d->m_stopForced)
msg = tr("The process was ended forcefully.");
else if (resultData.m_error != QProcess::UnknownError)
msg = userMessageForProcessError(resultData.m_error, runnable.command.executable());
appendMessage(msg, NormalMessageFormat);
m_stopReported = true;
d->m_stopReported = true;
reportStopped();
});
connect(&m_launcher, &QtcProcess::readyReadStandardOutput, this, [this] {
appendMessage(QString::fromUtf8(m_launcher.readAllStandardOutput()), StdOutFormat);
});
connect(&m_launcher, &QtcProcess::readyReadStandardError, this, [this] {
appendMessage(QString::fromUtf8(m_launcher.readAllStandardError()), StdErrFormat);
});
connect(&d->m_launcher, &ApplicationLauncher::appendMessage, this, &RunWorker::appendMessage);
const bool isDesktop = runnable.device.isNull()
|| runnable.device.dynamicCast<const DesktopDevice>();
if (isDesktop) {
connect(&m_launcher, &QtcProcess::started, this, [this] {
connect(&d->m_launcher, &ApplicationLauncher::started, this, [this] {
// Console processes only know their pid after being started
ProcessHandle pid = ProcessHandle(m_launcher.processId());
ProcessHandle pid = d->m_launcher.applicationPID();
runControl()->setApplicationProcessHandle(pid);
pid.activate();
reportStarted();
@@ -1275,20 +1278,21 @@ void SimpleTargetRunner::doStart(const Runnable &runnable)
return;
}
} else {
connect(&m_launcher, &QtcProcess::started, this, &RunWorker::reportStarted);
connect(&d->m_launcher, &ApplicationLauncher::started, this, &RunWorker::reportStarted);
}
m_launcher.start();
d->m_launcher.setRunnable(runnable);
d->m_launcher.start();
}
void SimpleTargetRunner::stop()
{
m_stopForced = true;
m_launcher.kill();
d->m_stopForced = true;
d->m_launcher.stop();
}
void SimpleTargetRunner::setStarter(const std::function<void ()> &starter)
{
m_starter = starter;
d->m_starter = starter;
}

View File

@@ -25,7 +25,6 @@
#pragma once
#include "applicationlauncher.h"
#include "buildconfiguration.h"
#include "devicesupport/idevicefwd.h"
#include "projectexplorerconstants.h"
@@ -33,21 +32,21 @@
#include <utils/commandline.h>
#include <utils/environment.h>
#include <utils/icon.h>
#include <utils/outputformatter.h>
#include <utils/processhandle.h>
#include <utils/qtcassert.h>
#include <utils/qtcprocess.h>
#include <QHash>
#include <QProcess> // FIXME: Remove
#include <QVariant>
#include <functional>
#include <memory>
namespace Utils {
class Icon;
class MacroExpander;
class OutputLineParser;
class OutputFormatter;
} // Utils
namespace ProjectExplorer {
@@ -60,6 +59,7 @@ class Target;
namespace Internal {
class RunControlPrivate;
class RunWorkerPrivate;
class SimpleTargetRunnerPrivate;
} // Internal
@@ -285,7 +285,7 @@ private:
/**
* A simple TargetRunner for cases where a plain QtcProcess is
* A simple TargetRunner for cases where a plain ApplicationLauncher is
* sufficient for running purposes.
*/
@@ -295,6 +295,7 @@ class PROJECTEXPLORER_EXPORT SimpleTargetRunner : public RunWorker
public:
explicit SimpleTargetRunner(RunControl *runControl);
~SimpleTargetRunner() override;
protected:
void setStarter(const std::function<void()> &starter);
@@ -306,11 +307,7 @@ private:
const Runnable &runnable() const = delete;
Utils::QtcProcess m_launcher;
std::function<void()> m_starter;
bool m_stopReported = false;
bool m_stopForced = false;
const std::unique_ptr<Internal::SimpleTargetRunnerPrivate> d;
};
class PROJECTEXPLORER_EXPORT OutputFormatterFactory