ProcessInterface: Get rid of state() method

This is fully controlled by QtcProcess itself, so provide
general implementation of state() inside QtcProcess.

Task-number: QTCREATORBUG-27358
Change-Id: Id6f0b771ed933f870b80d6856c6d94896f946516
Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
Jarek Kobus
2022-04-12 11:18:09 +02:00
parent 160dc16921
commit 44c7020651
10 changed files with 52 additions and 56 deletions

View File

@@ -66,7 +66,7 @@ void SshRemoteProcess::emitFinished()
QtcProcess::emitFinished(); QtcProcess::emitFinished();
} }
void SshRemoteProcess::start() void SshRemoteProcess::startImpl()
{ {
QTC_ASSERT(!isRunning(), return); QTC_ASSERT(!isRunning(), return);
m_errorString.clear(); m_errorString.clear();
@@ -78,7 +78,7 @@ void SshRemoteProcess::start()
} }
qCDebug(sshLog) << "starting remote process:" << cmd.toUserOutput(); qCDebug(sshLog) << "starting remote process:" << cmd.toUserOutput();
setCommand(cmd); setCommand(cmd);
QtcProcess::start(); QtcProcess::startImpl();
} }
ProcessResultData SshRemoteProcess::resultData() const ProcessResultData SshRemoteProcess::resultData() const

View File

@@ -41,7 +41,7 @@ public:
SshRemoteProcess(const QString &command, const QStringList &connectionArgs); SshRemoteProcess(const QString &command, const QStringList &connectionArgs);
void requestX11Forwarding(const QString &displayName); void requestX11Forwarding(const QString &displayName);
void start() override; void startImpl() override;
Utils::ProcessResultData resultData() const override; Utils::ProcessResultData resultData() const override;
Utils::CommandLine fullLocalCommandLine(bool inTerminal = false) const; Utils::CommandLine fullLocalCommandLine(bool inTerminal = false) const;

View File

@@ -110,8 +110,6 @@ private:
// It's being called in Starting or Running state. // It's being called in Starting or Running state.
virtual void sendControlSignal(ControlSignal controlSignal) = 0; virtual void sendControlSignal(ControlSignal controlSignal) = 0;
virtual QProcess::ProcessState state() const = 0;
// It's being called only in Starting state. // It's being called only in Starting state.
virtual bool waitForStarted(int msecs) = 0; virtual bool waitForStarted(int msecs) = 0;

View File

@@ -361,8 +361,6 @@ private:
} }
} }
QProcess::ProcessState state() const final { return m_process->state(); }
bool waitForStarted(int msecs) final { return m_process->waitForStarted(msecs); } bool waitForStarted(int msecs) final { return m_process->waitForStarted(msecs); }
bool waitForReadyRead(int msecs) final { return m_process->waitForReadyRead(msecs); } bool waitForReadyRead(int msecs) final { return m_process->waitForReadyRead(msecs); }
bool waitForFinished(int msecs) final { return m_process->waitForFinished(msecs); } bool waitForFinished(int msecs) final { return m_process->waitForFinished(msecs); }
@@ -460,8 +458,6 @@ private:
} }
} }
QProcess::ProcessState state() const final { return m_handle->state(); }
bool waitForStarted(int msecs) final { return m_handle->waitForStarted(msecs); } bool waitForStarted(int msecs) final { return m_handle->waitForStarted(msecs); }
bool waitForReadyRead(int msecs) final { return m_handle->waitForReadyRead(msecs); } bool waitForReadyRead(int msecs) final { return m_handle->waitForReadyRead(msecs); }
bool waitForFinished(int msecs) final { return m_handle->waitForFinished(msecs); } bool waitForFinished(int msecs) final { return m_handle->waitForFinished(msecs); }
@@ -564,6 +560,7 @@ public:
ProcessResult interpretExitCode(int exitCode); ProcessResult interpretExitCode(int exitCode);
QProcess::ProcessState m_state = QProcess::NotRunning;
QProcess::ProcessChannelMode m_processChannelMode = QProcess::SeparateChannels; QProcess::ProcessChannelMode m_processChannelMode = QProcess::SeparateChannels;
qint64 m_processId = 0; qint64 m_processId = 0;
qint64 m_applicationMainThreadId = 0; qint64 m_applicationMainThreadId = 0;
@@ -601,6 +598,8 @@ void QtcProcessPrivate::clearForRun()
m_stdErr.clearForRun(); m_stdErr.clearForRun();
m_stdErr.codec = m_codec; m_stdErr.codec = m_codec;
m_result = ProcessResult::StartFailed; m_result = ProcessResult::StartFailed;
m_state = QProcess::NotRunning;
m_processId = 0; m_processId = 0;
m_applicationMainThreadId = 0; m_applicationMainThreadId = 0;
m_resultData = {}; m_resultData = {};
@@ -780,9 +779,14 @@ void QtcProcess::setUseCtrlCStub(bool enabled)
void QtcProcess::start() void QtcProcess::start()
{ {
// TODO: Uncomment when we de-virtualize start() QTC_ASSERT(state() == QProcess::NotRunning, return);
// QTC_ASSERT(state() == QProcess::NotRunning, return); d->clearForRun();
d->m_state = QProcess::Starting;
startImpl();
}
void QtcProcess::startImpl()
{
ProcessInterface *processImpl = nullptr; ProcessInterface *processImpl = nullptr;
if (d->m_setup.m_commandLine.executable().needsDevice()) { if (d->m_setup.m_commandLine.executable().needsDevice()) {
if (s_deviceHooks.processImplHook) { // TODO: replace "if" with an assert for the hook if (s_deviceHooks.processImplHook) { // TODO: replace "if" with an assert for the hook
@@ -797,7 +801,6 @@ void QtcProcess::start()
processImpl = d->createProcessInterface(); processImpl = d->createProcessInterface();
} }
QTC_ASSERT(processImpl, return); QTC_ASSERT(processImpl, return);
d->clearForRun();
d->setProcessInterface(processImpl); d->setProcessInterface(processImpl);
d->m_process->m_setup = d->m_setup; d->m_process->m_setup = d->m_setup;
d->m_process->m_setup.m_commandLine = d->fullCommandLine(); d->m_process->m_setup.m_commandLine = d->fullCommandLine();
@@ -811,25 +814,25 @@ void QtcProcess::start()
void QtcProcess::terminate() void QtcProcess::terminate()
{ {
if (d->m_process) if (d->m_process && (d->m_state != QProcess::NotRunning))
d->m_process->sendControlSignal(ControlSignal::Terminate); d->m_process->sendControlSignal(ControlSignal::Terminate);
} }
void QtcProcess::kill() void QtcProcess::kill()
{ {
if (d->m_process) if (d->m_process && (d->m_state != QProcess::NotRunning))
d->m_process->sendControlSignal(ControlSignal::Kill); d->m_process->sendControlSignal(ControlSignal::Kill);
} }
void QtcProcess::interrupt() void QtcProcess::interrupt()
{ {
if (d->m_process) if (d->m_process && (d->m_state != QProcess::NotRunning))
d->m_process->sendControlSignal(ControlSignal::Interrupt); d->m_process->sendControlSignal(ControlSignal::Interrupt);
} }
void QtcProcess::kickoffProcess() void QtcProcess::kickoffProcess()
{ {
if (d->m_process) if (d->m_process && (d->m_state != QProcess::NotRunning))
d->m_process->sendControlSignal(ControlSignal::KickOff); d->m_process->sendControlSignal(ControlSignal::KickOff);
} }
@@ -1147,9 +1150,7 @@ void QtcProcess::setProcessChannelMode(QProcess::ProcessChannelMode mode)
QProcess::ProcessState QtcProcess::state() const QProcess::ProcessState QtcProcess::state() const
{ {
if (d->m_process) return d->m_state;
return d->m_process->state();
return QProcess::NotRunning;
} }
bool QtcProcess::isRunning() const bool QtcProcess::isRunning() const
@@ -1165,18 +1166,24 @@ qint64 QtcProcess::processId() const
bool QtcProcess::waitForStarted(int msecs) bool QtcProcess::waitForStarted(int msecs)
{ {
QTC_ASSERT(d->m_process, return false); QTC_ASSERT(d->m_process, return false);
if (d->m_state != QProcess::Starting)
return false;
return s_waitForStarted.measureAndRun(&ProcessInterface::waitForStarted, d->m_process, msecs); return s_waitForStarted.measureAndRun(&ProcessInterface::waitForStarted, d->m_process, msecs);
} }
bool QtcProcess::waitForReadyRead(int msecs) bool QtcProcess::waitForReadyRead(int msecs)
{ {
QTC_ASSERT(d->m_process, return false); QTC_ASSERT(d->m_process, return false);
if (d->m_state == QProcess::NotRunning)
return false;
return d->m_process->waitForReadyRead(msecs); return d->m_process->waitForReadyRead(msecs);
} }
bool QtcProcess::waitForFinished(int msecs) bool QtcProcess::waitForFinished(int msecs)
{ {
QTC_ASSERT(d->m_process, return false); QTC_ASSERT(d->m_process, return false);
if (d->m_state == QProcess::NotRunning)
return false;
return d->m_process->waitForFinished(msecs); return d->m_process->waitForFinished(msecs);
} }
@@ -1198,6 +1205,7 @@ qint64 QtcProcess::write(const QByteArray &input)
{ {
QTC_ASSERT(processMode() == ProcessMode::Writer, return -1); QTC_ASSERT(processMode() == ProcessMode::Writer, return -1);
QTC_ASSERT(d->m_process, return -1); QTC_ASSERT(d->m_process, return -1);
QTC_ASSERT(state() == QProcess::Running, return -1);
return d->m_process->write(input); return d->m_process->write(input);
} }
@@ -1543,6 +1551,9 @@ void QtcProcessPrivate::slotTimeout()
void QtcProcessPrivate::handleStarted(qint64 processId, qint64 applicationMainThreadId) void QtcProcessPrivate::handleStarted(qint64 processId, qint64 applicationMainThreadId)
{ {
QTC_CHECK(m_state == QProcess::Starting);
m_state = QProcess::Running;
m_processId = processId; m_processId = processId;
m_applicationMainThreadId = applicationMainThreadId; m_applicationMainThreadId = applicationMainThreadId;
emitStarted(); emitStarted();
@@ -1550,6 +1561,8 @@ void QtcProcessPrivate::handleStarted(qint64 processId, qint64 applicationMainTh
void QtcProcessPrivate::handleReadyRead(const QByteArray &outputData, const QByteArray &errorData) void QtcProcessPrivate::handleReadyRead(const QByteArray &outputData, const QByteArray &errorData)
{ {
QTC_CHECK(m_state == QProcess::Running);
// TODO: check why we need this timer? // TODO: check why we need this timer?
m_hangTimerCount = 0; m_hangTimerCount = 0;
// TODO: store a copy of m_processChannelMode on start()? Currently we assert that state // TODO: store a copy of m_processChannelMode on start()? Currently we assert that state
@@ -1583,6 +1596,19 @@ void QtcProcessPrivate::handleDone(const ProcessResultData &data)
{ {
m_resultData = data; m_resultData = data;
switch (m_state) {
case QProcess::NotRunning:
QTC_CHECK(false); // Can't happen
break;
case QProcess::Starting:
QTC_CHECK(m_resultData.m_error == QProcess::FailedToStart);
break;
case QProcess::Running:
QTC_CHECK(m_resultData.m_error != QProcess::FailedToStart);
break;
}
m_state = QProcess::NotRunning;
// This code (255) is being returned by QProcess when FailedToStart error occurred // This code (255) is being returned by QProcess when FailedToStart error occurred
if (m_resultData.m_error == QProcess::FailedToStart) if (m_resultData.m_error == QProcess::FailedToStart)
m_resultData.m_exitCode = 0xFF; m_resultData.m_exitCode = 0xFF;

View File

@@ -59,7 +59,7 @@ public:
// ProcessInterface related // ProcessInterface related
virtual void start(); void start();
virtual void terminate(); virtual void terminate();
virtual void kill(); virtual void kill();
@@ -74,7 +74,7 @@ public:
virtual qint64 processId() const; virtual qint64 processId() const;
qint64 applicationMainThreadId() const; qint64 applicationMainThreadId() const;
virtual QProcess::ProcessState state() const; QProcess::ProcessState state() const;
virtual ProcessResultData resultData() const; virtual ProcessResultData resultData() const;
int exitCode() const; int exitCode() const;
@@ -201,6 +201,7 @@ signals:
protected: protected:
// TODO: remove these methods on QtcProcess de-virtualization // TODO: remove these methods on QtcProcess de-virtualization
virtual void startImpl();
virtual void emitStarted(); virtual void emitStarted();
virtual void emitFinished(); virtual void emitFinished();

View File

@@ -513,16 +513,6 @@ bool TerminalImpl::isRunning() const
#endif #endif
} }
QProcess::ProcessState TerminalImpl::state() const
{
#ifdef Q_OS_WIN
return (d->m_pid != nullptr) ? QProcess::Running : QProcess::NotRunning;
#else
return (d->m_stubSocket && d->m_stubSocket->isOpen())
? QProcess::Running : d->m_process.state();
#endif
}
QString TerminalImpl::stubServerListen() QString TerminalImpl::stubServerListen()
{ {
#ifdef Q_OS_WIN #ifdef Q_OS_WIN

View File

@@ -56,8 +56,6 @@ private:
// intentionally no-op without an assert // intentionally no-op without an assert
bool waitForFinished(int) final { return false; } bool waitForFinished(int) final { return false; }
QProcess::ProcessState state() const final;
// OK, however, impl looks a bit different (!= NotRunning vs == Running). // OK, however, impl looks a bit different (!= NotRunning vs == Running).
// Most probably changing it into (== Running) should be OK. // Most probably changing it into (== Running) should be OK.
bool isRunning() const; bool isRunning() const;

View File

@@ -107,7 +107,7 @@ public:
DockerDeviceProcess(const QSharedPointer<const IDevice> &device, QObject *parent = nullptr); DockerDeviceProcess(const QSharedPointer<const IDevice> &device, QObject *parent = nullptr);
~DockerDeviceProcess() {} ~DockerDeviceProcess() {}
void start() override; void startImpl() override;
void interrupt() override; void interrupt() override;
const QSharedPointer<const IDevice> m_device; const QSharedPointer<const IDevice> m_device;
@@ -120,7 +120,7 @@ DockerDeviceProcess::DockerDeviceProcess(const QSharedPointer<const IDevice> &de
setProcessMode(ProcessMode::Writer); setProcessMode(ProcessMode::Writer);
} }
void DockerDeviceProcess::start() void DockerDeviceProcess::startImpl()
{ {
QTC_ASSERT(state() == QProcess::NotRunning, return); QTC_ASSERT(state() == QProcess::NotRunning, return);
DockerDevice::ConstPtr dockerDevice = qSharedPointerCast<const DockerDevice>(m_device); DockerDevice::ConstPtr dockerDevice = qSharedPointerCast<const DockerDevice>(m_device);
@@ -139,7 +139,7 @@ void DockerDeviceProcess::start()
setCommand(command); setCommand(command);
LOG("Running process:" << command.toUserOutput() << "in" << workingDirectory().toUserOutput()); LOG("Running process:" << command.toUserOutput() << "in" << workingDirectory().toUserOutput());
QtcProcess::start(); QtcProcess::startImpl();
} }
void DockerDeviceProcess::interrupt() void DockerDeviceProcess::interrupt()

View File

@@ -94,7 +94,7 @@ SshDeviceProcess::~SshDeviceProcess()
d->setState(SshDeviceProcessPrivate::Inactive); d->setState(SshDeviceProcessPrivate::Inactive);
} }
void SshDeviceProcess::start() void SshDeviceProcess::startImpl()
{ {
QTC_ASSERT(d->state == SshDeviceProcessPrivate::Inactive, return); QTC_ASSERT(d->state == SshDeviceProcessPrivate::Inactive, return);
QTC_ASSERT(usesTerminal() || !commandLine().isEmpty(), return); QTC_ASSERT(usesTerminal() || !commandLine().isEmpty(), return);
@@ -140,22 +140,6 @@ void SshDeviceProcess::kill()
d->doSignal(Signal::Kill); d->doSignal(Signal::Kill);
} }
QProcess::ProcessState SshDeviceProcess::state() const
{
switch (d->state) {
case SshDeviceProcessPrivate::Inactive:
return QProcess::NotRunning;
case SshDeviceProcessPrivate::Connecting:
case SshDeviceProcessPrivate::Connected:
return QProcess::Starting;
case SshDeviceProcessPrivate::ProcessRunning:
return QProcess::Running;
default:
QTC_CHECK(false);
return QProcess::NotRunning;
}
}
ProcessResultData SshDeviceProcess::resultData() const ProcessResultData SshDeviceProcess::resultData() const
{ {
const ProcessResultData result = QtcProcess::resultData(); const ProcessResultData result = QtcProcess::resultData();
@@ -190,7 +174,7 @@ void SshDeviceProcess::handleConnected()
if (usesTerminal()) { if (usesTerminal()) {
setAbortOnMetaChars(false); setAbortOnMetaChars(false);
setCommand(d->remoteProcess->fullLocalCommandLine(true)); setCommand(d->remoteProcess->fullLocalCommandLine(true));
QtcProcess::start(); QtcProcess::startImpl();
} else { } else {
connect(d->remoteProcess.get(), &QtcProcess::started, connect(d->remoteProcess.get(), &QtcProcess::started,
this, &SshDeviceProcess::handleProcessStarted); this, &SshDeviceProcess::handleProcessStarted);

View File

@@ -42,12 +42,11 @@ public:
explicit SshDeviceProcess(const QSharedPointer<const IDevice> &device, QObject *parent = nullptr); explicit SshDeviceProcess(const QSharedPointer<const IDevice> &device, QObject *parent = nullptr);
~SshDeviceProcess() override; ~SshDeviceProcess() override;
void start() override; void startImpl() override;
void interrupt() override; void interrupt() override;
void terminate() override; void terminate() override;
void kill() override; void kill() override;
QProcess::ProcessState state() const override;
Utils::ProcessResultData resultData() const override; Utils::ProcessResultData resultData() const override;
QByteArray readAllStandardOutput() override; QByteArray readAllStandardOutput() override;