diff --git a/src/viam/sdk/module/signal_manager.cpp b/src/viam/sdk/module/signal_manager.cpp index 5946f00d2..418667aff 100644 --- a/src/viam/sdk/module/signal_manager.cpp +++ b/src/viam/sdk/module/signal_manager.cpp @@ -1,22 +1,79 @@ #include +#ifdef _WIN32 +#include +#else #include #include +#endif + +#include namespace viam { namespace sdk { +#ifdef _WIN32 +SignalManager* SignalManager::instance_ = nullptr; +#endif + SignalManager::SignalManager() { +#ifdef _WIN32 + SignalManager::instance_ = this; + SetConsoleCtrlHandler(SignalManager::console_handler_routine_, TRUE); +#else sigemptyset(&sigset_); sigaddset(&sigset_, SIGINT); sigaddset(&sigset_, SIGTERM); pthread_sigmask(SIG_BLOCK, &sigset_, NULL); +#endif +} + +SignalManager::~SignalManager() { +#ifdef _WIN32 + SetConsoleCtrlHandler(NULL, FALSE); + if (signal_event_ != INVALID_HANDLE_VALUE) { + CloseHandle(signal_event_); + } + SignalManager::instance_ = nullptr; +#endif } int SignalManager::wait() { +#ifdef _WIN32 + signal_event_ = CreateEvent(NULL, TRUE, FALSE, NULL); + if (signal_event_ == INVALID_HANDLE_VALUE) { + throw std::runtime_error("Failed to create signal event"); + } + WaitForSingleObject(signal_event_, INFINITE); + return static_cast(signal_code_); +#else int sig = 0; return sigwait(&sigset_, &sig); +#endif +} + +#ifdef _WIN32 + +BOOL WINAPI SignalManager::console_handler_routine_(DWORD dwCtrlType) { + if (dwCtrlType == CTRL_C_EVENT || dwCtrlType == CTRL_BREAK_EVENT) { + SignalManager::instance_->handle_signal_(SIGINT); + return TRUE; + } else if (dwCtrlType == CTRL_CLOSE_EVENT || dwCtrlType == CTRL_LOGOFF_EVENT || + dwCtrlType == CTRL_SHUTDOWN_EVENT) { + SignalManager::instance_->handle_signal_(SIGTERM); + return TRUE; + } + return FALSE; } +void SignalManager::handle_signal_(int signal) { + if (signal_event_ != INVALID_HANDLE_VALUE) { + signal_code_ = signal; + SetEvent(signal_event_); + } +} + +#endif + } // namespace sdk } // namespace viam diff --git a/src/viam/sdk/module/signal_manager.hpp b/src/viam/sdk/module/signal_manager.hpp index 90e62d12d..5eb7fb4d3 100644 --- a/src/viam/sdk/module/signal_manager.hpp +++ b/src/viam/sdk/module/signal_manager.hpp @@ -2,6 +2,10 @@ #include +#ifdef _WIN32 +#include +#endif + namespace viam { namespace sdk { @@ -14,13 +18,25 @@ class SignalManager { /// @brief Creates a new SignalManager. explicit SignalManager(); + /// @brief Destructor. + ~SignalManager(); + /// @brief Wait for SignalManager to receive SIGINT or SIGTERM. /// @return The signal number if successful. - /// @throws `std::runtime_error` if the underlying sigwait call was unsuccessful. + /// @throws `std::runtime_error` if the underlying wait operation was unsuccessful. int wait(); private: +#ifdef _WIN32 + static BOOL WINAPI console_handler_routine_(DWORD dwCtrlType); + void handle_signal_(int signal); + + static SignalManager* instance_; + HANDLE signal_event_ = INVALID_HANDLE_VALUE; + int signal_code_ = 0; +#else sigset_t sigset_; +#endif }; } // namespace sdk