gui: remove dead code (ninepconnection, streamfsm)

These were replaced by NativeStreamer which uses ollie-9p subprocess
for streaming reads.
This commit is contained in:
Levi Neely 2026-08-07 18:07:16 +02:00
parent 6fda37ae96
commit e10912de08
4 changed files with 0 additions and 413 deletions

View File

@ -1,191 +0,0 @@
#include "ninepconnection.h"
/*
* TRANSITION TABLE
* ================
*
* State | Event | Guard | Next State | Actions
* -------------|--------------|------------------------|--------------|------------------
* Disconnected | EvStart | | Connecting | spawnProcess
* Connecting | EvOpenMarker | | Connected | emit connected
* Connecting | EvExitFail | canRetry | RetryWait | scheduleRetry
* Connecting | EvExitFail | !canRetry | Disconnected |
* Connected | EvExitOk | | Connected | scheduleRetry (silent)
* Connected | EvExitFail | canRetry | RetryWait | emit disconnected, scheduleRetry
* Connected | EvExitFail | !canRetry | Disconnected | emit disconnected
* RetryWait | EvRetryTimer | | Connecting | spawnProcess
* Any | EvStop | | Disconnected | killProcess, emit disconnected (if was Connected)
*
* Signals:
* - connected: emitted when entering Connected from any other state
* - disconnected: emitted when leaving Connected for any other state
*/
NinePConnection::NinePConnection(QObject *parent)
: QObject(parent)
{
m_retryTimer.setSingleShot(true);
connect(&m_retryTimer, &QTimer::timeout, this, [this]() { dispatch(EvRetryTimer); });
}
NinePConnection::~NinePConnection()
{
stop();
}
void NinePConnection::start(const QString &program, const QStringList &args, int retryMs, int maxRetries)
{
m_program = program;
m_args = args;
m_retryMs = retryMs;
m_maxRetries = maxRetries;
m_retryCount = 0;
dispatch(EvStart);
}
void NinePConnection::stop()
{
dispatch(EvStop);
}
void NinePConnection::dispatch(Event ev)
{
State next = m_state;
switch (m_state) {
case Disconnected:
if (ev == EvStart) {
next = Connecting;
spawnProcess();
}
break;
case Connecting:
if (ev == EvStop) {
next = Disconnected;
killProcess();
} else if (ev == EvOpenMarker) {
next = Connected;
} else if (ev == EvExitFail) {
bool canRetry = m_retryMs > 0 && (m_maxRetries == 0 || m_retryCount < m_maxRetries);
if (canRetry) {
next = RetryWait;
++m_retryCount;
scheduleRetry();
} else {
next = Disconnected;
}
}
break;
case Connected:
if (ev == EvStop) {
next = Disconnected;
killProcess();
} else if (ev == EvExitOk) {
// Silent restart - stay Connected
m_retryCount = 0;
scheduleRetry();
} else if (ev == EvExitFail) {
bool canRetry = m_retryMs > 0 && (m_maxRetries == 0 || m_retryCount < m_maxRetries);
if (canRetry) {
next = RetryWait;
++m_retryCount;
scheduleRetry();
} else {
next = Disconnected;
}
}
break;
case RetryWait:
if (ev == EvStop) {
next = Disconnected;
m_retryTimer.stop();
} else if (ev == EvRetryTimer) {
next = Connecting;
spawnProcess();
}
break;
}
if (next != m_state)
enter(next);
}
void NinePConnection::enter(State state)
{
State prev = m_state;
m_state = state;
emit stateChanged(state);
if (state == Connected && prev != Connected)
emit connected();
else if (prev == Connected && state != Connected)
emit disconnected();
}
void NinePConnection::spawnProcess()
{
if (m_process) return;
m_stderr.clear();
m_openMarkerSeen = false;
m_process = new QProcess(this);
connect(m_process, &QProcess::readyReadStandardOutput, this, &NinePConnection::onStdout);
connect(m_process, &QProcess::readyReadStandardError, this, &NinePConnection::onStderr);
connect(m_process, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
this, &NinePConnection::onFinished);
m_process->start(m_program, m_args);
}
void NinePConnection::killProcess()
{
m_retryTimer.stop();
if (m_process) {
m_process->disconnect(this);
m_process->kill();
m_process->waitForFinished(1000);
m_process->deleteLater();
m_process = nullptr;
}
}
void NinePConnection::scheduleRetry()
{
if (m_retryMs > 0)
m_retryTimer.start(m_retryMs);
else
spawnProcess();
}
void NinePConnection::onStdout()
{
const QByteArray data = m_process->readAllStandardOutput();
if (!data.isEmpty())
emit readyRead(data);
}
void NinePConnection::onStderr()
{
m_stderr += m_process->readAllStandardError();
while (true) {
int end = m_stderr.indexOf('\n');
if (end < 0) break;
QByteArray line = m_stderr.left(end).trimmed();
m_stderr.remove(0, end + 1);
if (line == "OLLIE_9P_OPEN") {
m_openMarkerSeen = true;
dispatch(EvOpenMarker);
}
}
}
void NinePConnection::onFinished(int exitCode, QProcess::ExitStatus)
{
if (!m_process) return;
m_process->deleteLater();
m_process = nullptr;
bool success = (exitCode == 0 && m_openMarkerSeen);
dispatch(success ? EvExitOk : EvExitFail);
}

View File

@ -1,61 +0,0 @@
#ifndef NINEPCONNECTION_H
#define NINEPCONNECTION_H
#include <QObject>
#include <QProcess>
#include <QTimer>
#include <QStringList>
/**
* NinePConnection - Resilient 9P subprocess connection.
*
* State machine with explicit events and transition table.
*/
class NinePConnection : public QObject
{
Q_OBJECT
public:
enum State { Disconnected, Connecting, Connected, RetryWait };
Q_ENUM(State)
enum Event { EvStart, EvStop, EvOpenMarker, EvExitOk, EvExitFail, EvRetryTimer };
Q_ENUM(Event)
explicit NinePConnection(QObject *parent = nullptr);
~NinePConnection() override;
void start(const QString &program, const QStringList &args, int retryMs = 4000, int maxRetries = 0);
void stop();
State state() const { return m_state; }
signals:
void connected();
void disconnected();
void readyRead(const QByteArray &data);
void stateChanged(State state);
private slots:
void onStdout();
void onStderr();
void onFinished(int exitCode, QProcess::ExitStatus status);
private:
void dispatch(Event ev);
void enter(State state);
void spawnProcess();
void killProcess();
void scheduleRetry();
QProcess *m_process = nullptr;
QTimer m_retryTimer;
QString m_program;
QStringList m_args;
QByteArray m_stderr;
State m_state = Disconnected;
int m_retryMs = 4000;
int m_maxRetries = 0;
int m_retryCount = 0;
bool m_openMarkerSeen = false;
};
#endif // NINEPCONNECTION_H

View File

@ -1,92 +0,0 @@
#include "streamfsm.h"
StreamFsm::StreamFsm(RestartPolicy policy, QObject *parent)
: QObject(parent)
, m_policy(policy)
{
}
StreamFsm::~StreamFsm()
{
stop();
}
void StreamFsm::start(const QString &program, const QStringList &args)
{
m_program = program;
m_args = args;
if (m_state == Idle)
startProcess();
}
void StreamFsm::stop()
{
if (m_state == Idle)
return;
if (m_proc) {
// Disconnect before killing so onFinished doesn't fire during teardown.
m_proc->disconnect();
m_proc->kill();
m_proc->waitForFinished(1000);
m_proc->deleteLater();
m_proc = nullptr;
}
transitTo(Idle);
}
void StreamFsm::setGuard(std::function<bool()> guard)
{
m_guard = std::move(guard);
}
void StreamFsm::startProcess()
{
if (m_state != Idle)
return;
m_proc = new QProcess(this);
connect(m_proc, &QProcess::readyReadStandardOutput,
this, &StreamFsm::onReadyRead);
connect(m_proc,
QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
this, &StreamFsm::onFinished);
m_proc->start(m_program, m_args);
transitTo(Running);
}
void StreamFsm::onReadyRead()
{
QByteArray data = m_proc->readAllStandardOutput();
if (!data.isEmpty())
emit readyRead(data);
}
void StreamFsm::onFinished(int, QProcess::ExitStatus)
{
// Clean up the finished process.
m_proc->deleteLater();
m_proc = nullptr;
transitTo(Idle);
// Decide what to do next based on policy.
switch (m_policy) {
case Oneshot:
emit died();
break;
case Looping:
startProcess();
break;
case Guarded:
if (m_guard && m_guard())
startProcess();
else
emit died();
break;
}
}
void StreamFsm::transitTo(State s)
{
m_state = s;
}

View File

@ -1,69 +0,0 @@
#ifndef STREAMFSM_H
#define STREAMFSM_H
#include <QObject>
#include <QProcess>
#include <QString>
#include <QStringList>
#include <functional>
/// A formal 2-state FSM wrapping a QProcess streaming lifecycle.
///
/// States: Idle ──start()──→ Running ──stop()──→ Idle
/// Running ──process exit──→ Idle ──[policy]──→ Running | emit died()
///
/// Three restart policies:
/// Oneshot — process runs once, then emits died()
/// Looping — process always restarts after exit
/// Guarded — process restarts only if guard() returns true
///
/// All signal connections are managed internally. stop() is safe to call
/// from any state; it disconnects before killing to prevent spurious signals.
class StreamFsm : public QObject
{
Q_OBJECT
public:
enum State { Idle, Running };
enum RestartPolicy { Oneshot, Looping, Guarded };
explicit StreamFsm(RestartPolicy policy, QObject *parent = nullptr);
~StreamFsm();
State state() const { return m_state; }
RestartPolicy policy() const { return m_policy; }
/// Store program/args and start the process (no-op if already Running).
void start(const QString &program, const QStringList &args);
/// Kill the process and transition to Idle. Does not emit died().
void stop();
/// Guard predicate for Guarded policy — called after exit to decide
/// whether to restart. Not used for Oneshot or Looping.
void setGuard(std::function<bool()> guard);
signals:
/// Emitted with data from the process's stdout (partial reads).
void readyRead(const QByteArray &data);
/// Emitted when the process has exited and will NOT be restarted
/// (Oneshot policy, or Guarded policy with a false guard).
void died();
private slots:
void onReadyRead();
void onFinished(int exitCode, QProcess::ExitStatus status);
private:
void startProcess();
void transitTo(State s);
State m_state = Idle;
QProcess *m_proc = nullptr;
RestartPolicy m_policy;
std::function<bool()> m_guard;
QString m_program;
QStringList m_args;
};
#endif // STREAMFSM_H