CmdBridge: Implement clean exit

Change-Id: I248fbe5a24f55f6d7ba9ea8e0093eda702baaad1
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
Marcus Tillmanns
2024-07-09 06:40:32 +02:00
parent 495418d4c4
commit 0405801f17
3 changed files with 30 additions and 3 deletions

View File

@@ -239,9 +239,11 @@ Client::Client(const Utils::FilePath &remoteCmdBridgePath)
Client::~Client() Client::~Client()
{ {
d->thread->quit(); if (d->thread->isRunning()) {
exit();
d->thread->wait(); d->thread->wait();
} }
}
expected_str<QFuture<Environment>> Client::start() expected_str<QFuture<Environment>> Client::start()
{ {
@@ -303,10 +305,14 @@ expected_str<QFuture<Environment>> Client::start()
func(QVariantMap{ func(QVariantMap{
{"Type", "error"}, {"Type", "error"},
{"Id", id}, {"Id", id},
{"Error", QString("Process exited: %1").arg(d->process->errorString())}}); {"Error", QString("Process exited: %1").arg(d->process->errorString())},
{"ErrorType", (d->process->exitCode() == 0 ? "NormalExit" : "ErrorExit")}});
} }
emit done(d->process->resultData()); emit done(d->process->resultData());
d->process->deleteLater();
d->process = nullptr;
QThread::currentThread()->quit();
}); });
auto stateMachine = [state = int(0), packetSize(0), packetData = QByteArray(), this]( auto stateMachine = [state = int(0), packetSize(0), packetData = QByteArray(), this](
@@ -374,6 +380,9 @@ expected_str<QFuture<Environment>> Client::start()
d->process->start(); d->process->start();
if (!d->process)
return make_unexpected(Tr::tr("Failed starting bridge process"));
if (!d->process->waitForStarted()) if (!d->process->waitForStarted())
return make_unexpected( return make_unexpected(
Tr::tr("Failed starting bridge process: %1").arg(d->process->errorString())); Tr::tr("Failed starting bridge process: %1").arg(d->process->errorString()));
@@ -419,6 +428,10 @@ static Utils::expected_str<QFuture<R>> createJob(
promise->setException( promise->setException(
std::make_exception_ptr(std::system_error(ENOENT, std::generic_category()))); std::make_exception_ptr(std::system_error(ENOENT, std::generic_category())));
promise->finish(); promise->finish();
} else if (errType == "NormalExit") {
promise->setException(
std::make_exception_ptr(std::runtime_error(err.toStdString())));
promise->finish();
} else { } else {
qCWarning(clientLog) << "Error (" << errType << "):" << err; qCWarning(clientLog) << "Error (" << errType << "):" << err;
promise->setException( promise->setException(
@@ -799,6 +812,15 @@ Utils::expected_str<QFuture<void>> Client::signalProcess(int pid, Utils::Control
"signalsuccess"); "signalsuccess");
} }
void Client::exit()
{
try {
createVoidJob(d.get(), QCborMap{{"Type", "exit"}}, "exitres")->waitForFinished();
} catch (...) {
return;
}
}
Utils::expected_str<QFuture<Client::Stat>> Client::stat(const QString &path) Utils::expected_str<QFuture<Client::Stat>> Client::stat(const QString &path)
{ {
return createJob<Stat>( return createJob<Stat>(

View File

@@ -112,6 +112,9 @@ public:
Utils::expected_str<QFuture<void>> signalProcess(int pid, Utils::ControlSignal signal); Utils::expected_str<QFuture<void>> signalProcess(int pid, Utils::ControlSignal signal);
protected:
void exit();
signals: signals:
void done(const Utils::ProcessResultData &resultData); void done(const Utils::ProcessResultData &resultData);

View File

@@ -395,6 +395,8 @@ func processCommand(watcher *WatcherHandler, cmd command, out chan<- []byte) {
Error: cmd.Error, Error: cmd.Error,
}) })
out <- result out <- result
case "exit":
os.Exit(0)
} }
} }