Skip to content

Commit fddae77

Browse files
authored
[RSDK-10385] Windows signal handling (#407)
1 parent 1b0f4a8 commit fddae77

File tree

2 files changed

+74
-1
lines changed

2 files changed

+74
-1
lines changed
+57
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,79 @@
11
#include <viam/sdk/module/signal_manager.hpp>
22

3+
#ifdef _WIN32
4+
#include <windows.h>
5+
#else
36
#include <csignal>
47
#include <pthread.h>
8+
#endif
9+
10+
#include <stdexcept>
511

612
namespace viam {
713
namespace sdk {
814

15+
#ifdef _WIN32
16+
SignalManager* SignalManager::instance_ = nullptr;
17+
#endif
18+
919
SignalManager::SignalManager() {
20+
#ifdef _WIN32
21+
SignalManager::instance_ = this;
22+
SetConsoleCtrlHandler(SignalManager::console_handler_routine_, TRUE);
23+
#else
1024
sigemptyset(&sigset_);
1125
sigaddset(&sigset_, SIGINT);
1226
sigaddset(&sigset_, SIGTERM);
1327
pthread_sigmask(SIG_BLOCK, &sigset_, NULL);
28+
#endif
29+
}
30+
31+
SignalManager::~SignalManager() {
32+
#ifdef _WIN32
33+
SetConsoleCtrlHandler(NULL, FALSE);
34+
if (signal_event_ != INVALID_HANDLE_VALUE) {
35+
CloseHandle(signal_event_);
36+
}
37+
SignalManager::instance_ = nullptr;
38+
#endif
1439
}
1540

1641
int SignalManager::wait() {
42+
#ifdef _WIN32
43+
signal_event_ = CreateEvent(NULL, TRUE, FALSE, NULL);
44+
if (signal_event_ == INVALID_HANDLE_VALUE) {
45+
throw std::runtime_error("Failed to create signal event");
46+
}
47+
WaitForSingleObject(signal_event_, INFINITE);
48+
return static_cast<DWORD>(signal_code_);
49+
#else
1750
int sig = 0;
1851
return sigwait(&sigset_, &sig);
52+
#endif
53+
}
54+
55+
#ifdef _WIN32
56+
57+
BOOL WINAPI SignalManager::console_handler_routine_(DWORD dwCtrlType) {
58+
if (dwCtrlType == CTRL_C_EVENT || dwCtrlType == CTRL_BREAK_EVENT) {
59+
SignalManager::instance_->handle_signal_(SIGINT);
60+
return TRUE;
61+
} else if (dwCtrlType == CTRL_CLOSE_EVENT || dwCtrlType == CTRL_LOGOFF_EVENT ||
62+
dwCtrlType == CTRL_SHUTDOWN_EVENT) {
63+
SignalManager::instance_->handle_signal_(SIGTERM);
64+
return TRUE;
65+
}
66+
return FALSE;
1967
}
2068

69+
void SignalManager::handle_signal_(int signal) {
70+
if (signal_event_ != INVALID_HANDLE_VALUE) {
71+
signal_code_ = signal;
72+
SetEvent(signal_event_);
73+
}
74+
}
75+
76+
#endif
77+
2178
} // namespace sdk
2279
} // namespace viam

src/viam/sdk/module/signal_manager.hpp

+17-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
#include <signal.h>
44

5+
#ifdef _WIN32
6+
#include <windows.h>
7+
#endif
8+
59
namespace viam {
610
namespace sdk {
711

@@ -14,13 +18,25 @@ class SignalManager {
1418
/// @brief Creates a new SignalManager.
1519
explicit SignalManager();
1620

21+
/// @brief Destructor.
22+
~SignalManager();
23+
1724
/// @brief Wait for SignalManager to receive SIGINT or SIGTERM.
1825
/// @return The signal number if successful.
19-
/// @throws `std::runtime_error` if the underlying sigwait call was unsuccessful.
26+
/// @throws `std::runtime_error` if the underlying wait operation was unsuccessful.
2027
int wait();
2128

2229
private:
30+
#ifdef _WIN32
31+
static BOOL WINAPI console_handler_routine_(DWORD dwCtrlType);
32+
void handle_signal_(int signal);
33+
34+
static SignalManager* instance_;
35+
HANDLE signal_event_ = INVALID_HANDLE_VALUE;
36+
int signal_code_ = 0;
37+
#else
2338
sigset_t sigset_;
39+
#endif
2440
};
2541

2642
} // namespace sdk

0 commit comments

Comments
 (0)