CppZmqZoltanExt 0.0.1
Loading...
Searching...
No Matches
interrupt.cpp
Go to the documentation of this file.
1/*
2MIT License
3
4Copyright (c) 2025 Luan Young
5
6Permission is hereby granted, free of charge, to any person obtaining a copy
7of this software and associated documentation files (the "Software"), to deal
8in the Software without restriction, including without limitation the rights
9to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10copies of the Software, and to permit persons to whom the Software is
11furnished to do so, subject to the following conditions:
12
13The above copyright notice and this permission notice shall be included in all
14copies or substantial portions of the Software.
15
16THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22SOFTWARE.
23*/
37
38#if !defined(WIN32)
39#include <signal.h>
40#else
41#include <csignal>
42#endif
43
44#include <atomic>
45
46namespace zmqzext {
47
48namespace {
49static std::atomic<bool> zmqzext_interrupted{false};
50static bool handlers_stored{false};
51#if !defined(WIN32)
52static struct sigaction stored_sigint;
53static struct sigaction stored_sigterm;
54#else
55static void (*stored_sigint_handler)(int) = nullptr;
56static void (*stored_sigterm_handler)(int) = nullptr;
57#endif
58
59void signal_handler(int /*signal*/) { zmqzext_interrupted.store(true, std::memory_order_relaxed); }
60
61#if !defined(WIN32)
62void store_signal_handlers() noexcept {
63 sigaction(SIGINT, nullptr, &stored_sigint);
64 sigaction(SIGTERM, nullptr, &stored_sigterm);
65 handlers_stored = true;
66}
67
68void setup_signal_handlers() noexcept {
69 struct sigaction action;
70 action.sa_handler = signal_handler;
71 action.sa_flags = 0;
72 sigemptyset(&action.sa_mask);
73
74 sigaction(SIGINT, &action, nullptr);
75 sigaction(SIGTERM, &action, nullptr);
76}
77#endif
78
79} // namespace
80
81#if !defined(WIN32)
83 // Store current handlers only if not already stored or after a restore
84 if (!handlers_stored) {
85 store_signal_handlers();
86 }
87 setup_signal_handlers();
88}
89
91 if (handlers_stored) {
92 sigaction(SIGINT, &stored_sigint, nullptr);
93 sigaction(SIGTERM, &stored_sigterm, nullptr);
94 handlers_stored = false;
95 }
96}
97#else
98void install_interrupt_handler() noexcept {
99 if (!handlers_stored) {
100 stored_sigint_handler = std::signal(SIGINT, signal_handler);
101 stored_sigterm_handler = std::signal(SIGTERM, signal_handler);
102 handlers_stored = true;
103 } else {
104 std::signal(SIGINT, signal_handler);
105 std::signal(SIGTERM, signal_handler);
106 }
107}
108
109void restore_interrupt_handler() noexcept {
110 if (handlers_stored) {
111 std::signal(SIGINT, stored_sigint_handler);
112 std::signal(SIGTERM, stored_sigterm_handler);
113 handlers_stored = false;
114 }
115}
116#endif
117
118bool is_interrupted() noexcept { return zmqzext_interrupted.load(std::memory_order_relaxed); }
119
120void reset_interrupted() noexcept { zmqzext_interrupted.store(false, std::memory_order_relaxed); }
121
122} // namespace zmqzext
Signal interrupt handling for graceful application shutdown.
CZZE_EXPORT bool is_interrupted() noexcept
Check if a program interrupt was received.
Definition: interrupt.cpp:118
CZZE_EXPORT void restore_interrupt_handler() noexcept
Restore the previously stored signal handlers.
Definition: interrupt.cpp:90
CZZE_EXPORT void install_interrupt_handler() noexcept
Install signal handlers for SIGINT and SIGTERM.
Definition: interrupt.cpp:82
CZZE_EXPORT void reset_interrupted() noexcept
Reset the interrupt flag to false.
Definition: interrupt.cpp:120
Signal definitions and utilities for actor inter-thread communication.