nekoray_Mahdi-zarei/src/sys/Process.cpp
2025-10-22 03:22:37 +03:30

107 lines
3.7 KiB
C++

#include "include/sys/Process.hpp"
#include "include/global/Configs.hpp"
#include <QTimer>
#include <QDir>
#include <QApplication>
#include "include/ui/mainwindow.h"
namespace Configs_sys {
CoreProcess::~CoreProcess() {
}
void CoreProcess::Kill() {
kill();
waitForFinished();
}
CoreProcess::CoreProcess(const QString &core_path, const QStringList &args) {
program = core_path;
arguments = args;
connect(this, &QProcess::readyReadStandardOutput, this, [&]() {
auto log = readAllStandardOutput();
if (!Configs::dataStore->core_running) {
if (log.contains("Core listening at")) {
// The core really started
Configs::dataStore->core_running = true;
MW_dialog_message("ExternalProcess", "CoreStarted," + Int2String(start_profile_when_core_is_up));
start_profile_when_core_is_up = -1;
} else if (log.contains("failed to serve")) {
// The core failed to start
kill();
}
}
if (log.contains("Extra process exited unexpectedly"))
{
MW_show_log("Extra Core exited, stopping profile...");
MW_dialog_message("ExternalProcess", "Crashed");
}
if (logCounter.fetchAndAddRelaxed(log.count("\n")) > Configs::dataStore->max_log_line) return;
MW_show_log(log);
});
connect(this, &QProcess::readyReadStandardError, this, [&]() {
auto log = readAllStandardError().trimmed();
MW_show_log(log);
});
connect(this, &QProcess::errorOccurred, this, [&](ProcessError error) {
if (error == FailedToStart) {
failed_to_start = true;
MW_show_log("start core error occurred: " + errorString() + "\n");
}
});
connect(this, &QProcess::stateChanged, this, [&](ProcessState state) {
if (state == NotRunning) {
Configs::dataStore->core_running = false;
qDebug() << "Core stated changed to not running";
}
if (!Configs::dataStore->prepare_exit && state == NotRunning) {
if (failed_to_start) return; // no retry
if (restarting) return;
MW_show_log("[Fatal] " + QObject::tr("Core exited, cleaning up..."));
runOnUiThread([=, this]
{
GetMainWindow()->profile_stop(true, true);
}, true);
// Retry rate limit
if (coreRestartTimer.isValid()) {
if (coreRestartTimer.restart() < 10 * 1000) {
coreRestartTimer = QElapsedTimer();
MW_show_log("[ERROR] " + QObject::tr("Core exits too frequently, stop automatic restart this profile."));
return;
}
} else {
coreRestartTimer.start();
}
// Restart
start_profile_when_core_is_up = Configs::dataStore->started_id;
MW_show_log("[Warn] " + QObject::tr("Restarting the core ..."));
setTimeout([=,this] { Restart(); }, this, 200);
}
});
}
void CoreProcess::Start() {
if (started) return;
started = true;
setEnvironment(QProcessEnvironment::systemEnvironment().toStringList());
start(program, arguments);
}
void CoreProcess::Restart() {
restarting = true;
kill();
waitForFinished(500);
started = false;
Start();
restarting = false;
}
} // namespace Configs_sys