From 466095efcb9398f400f27baba045643aede6814c Mon Sep 17 00:00:00 2001 From: MihailRis Date: Thu, 30 Jul 2026 23:47:06 +0300 Subject: [PATCH] add SystemProcess --- src/main.cpp | 1 + src/util/platform.cpp | 100 ++++++++++++++++++++++++++++++++++++++++-- src/util/platform.hpp | 5 ++- 3 files changed, 102 insertions(+), 4 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 77175bd8a..098d72a70 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -10,6 +10,7 @@ static debug::Logger logger("main"); static void sigterm_handler(int signum) { + logger.info() << "SIGTERM received"; Engine::getInstance().quit(); } diff --git a/src/util/platform.cpp b/src/util/platform.cpp index 88d42d34a..e0b2587b7 100644 --- a/src/util/platform.cpp +++ b/src/util/platform.cpp @@ -25,6 +25,7 @@ #endif #ifdef __linux__ #include + #include #endif namespace platform::internal { @@ -221,7 +222,98 @@ std::filesystem::path platform::get_executable_path() { #endif } -void platform::new_engine_instance( +class SystemProcess final : public Process { +public: +#ifdef __linux__ + SystemProcess(pid_t pid) : pid(pid) { + } + + ~SystemProcess() { + terminate(); + } +#elif defined(_WIN32) + SystemProcess(const PROCESS_INFORMATION& pi) + : processHandle(pi.hProcess), pid(pi.dwProcessId) { + if (pi.hThread != nullptr) { + CloseHandle(pi.hThread); + } + } + + ~SystemProcess() { + terminate(); + } +#endif + SystemProcess(const SystemProcess&) = delete; + SystemProcess(SystemProcess&&) noexcept = default; + SystemProcess& operator=(const SystemProcess&) = delete; + + SystemProcess& operator=(SystemProcess&& other) noexcept { + if (this != &other) { +#ifdef __linux__ + pid = other.pid; +#elif defined(_WIN32) + if (processHandle != nullptr) { + CloseHandle(processHandle); + } + processHandle = other.processHandle; + pid = other.pid; + other.processHandle = nullptr; + other.pid = 0; +#endif + } + return *this; + } + + bool isActive() const override { +#ifdef __linux__ + if (kill(pid, 0) == 0) { + return true; + } + return errno != ESRCH; +#elif defined(_WIN32) + if (processHandle == nullptr) { + return false; + } + DWORD exitCode; + if (GetExitCodeProcess(processHandle, &exitCode)) { + return exitCode == STILL_ACTIVE; + } + return false; +#endif + } + + void update() override {} + + void waitForEnd() override { +#ifdef __linux__ + waitpid(pid, nullptr, 0); +#elif defined(_WIN32) + if (processHandle != nullptr) { + WaitForSingleObject(processHandle, INFINITE); + } +#endif + }; + + void terminate() final override { +#ifdef __linux__ + kill(pid, SIGKILL); +#elif defined(_WIN32) + if (processHandle != nullptr) { + TerminateProcess(processHandle, 1); + WaitForSingleObject(processHandle, INFINITE); + } +#endif + } +private: +#ifdef __linux__ + pid_t pid; +#elif defined(_WIN32) + HANDLE processHandle = nullptr; + DWORD pid = 0; +#endif +}; + +std::unique_ptr platform::new_engine_instance( const std::vector& args, std::filesystem::path outputFile, bool subProcess @@ -317,11 +409,12 @@ void platform::new_engine_instance( std::to_string(GetLastError()) ); } + return std::make_unique(pi); } catch (const std::exception& err) { CloseHandle(job); CloseHandle(pi.hProcess); CloseHandle(pi.hThread); - return; + return nullptr; } } if (success) { @@ -368,7 +461,7 @@ void platform::new_engine_instance( _exit(127); } else { close(fd); - return; + return std::make_unique(pid); } } #endif // __APPLE_ @@ -393,6 +486,7 @@ void platform::new_engine_instance( ); } #endif + return nullptr; } bool platform::stdin_has_data() { diff --git a/src/util/platform.hpp b/src/util/platform.hpp index 2ff535248..18dc052b6 100644 --- a/src/util/platform.hpp +++ b/src/util/platform.hpp @@ -2,8 +2,11 @@ #include #include +#include #include +#include "interfaces/Process.hpp" + namespace platform { void configure_encoding(); /// @brief Get Environment locale in ISO format ll_CC @@ -18,7 +21,7 @@ namespace platform { /// @brief Get current process running executable path std::filesystem::path get_executable_path(); /// @brief Run a separate engine instance with specified arguments - void new_engine_instance( + std::unique_ptr new_engine_instance( const std::vector& args, std::filesystem::path outputFile, bool subProcess