ROS 2 rclcpp + rcl - jazzy  jazzy
ROS 2 C++ Client Library with ROS Client Library
signal_handler.hpp
1 // Copyright 2018 Open Source Robotics Foundation, Inc.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef RCLCPP__SIGNAL_HANDLER_HPP_
16 #define RCLCPP__SIGNAL_HANDLER_HPP_
17 
18 #include <atomic>
19 #include <csignal>
20 #include <mutex>
21 #include <thread>
22 
23 #include "rclcpp/logging.hpp"
24 #include "rclcpp/utilities.hpp"
25 
26 // includes for semaphore notification code
27 #if defined(_WIN32)
28 #include <windows.h>
29 #elif defined(__APPLE__)
30 #include <dispatch/dispatch.h>
31 #else // posix
32 #include <semaphore.h>
33 #endif
34 
35 // Determine if sigaction is available
36 #if __APPLE__ || _POSIX_C_SOURCE >= 1 || _XOPEN_SOURCE || _POSIX_SOURCE
37 #define RCLCPP_HAS_SIGACTION
38 #endif
39 
40 namespace rclcpp
41 {
42 
44 
55 class SignalHandler final
56 {
57 public:
59  static
62 
64  static
66  get_logger();
67 
69 
75  bool
76  install(SignalHandlerOptions signal_handler_options = SignalHandlerOptions::All);
77 
80 
83  bool
84  uninstall();
85 
87  bool
88  is_installed();
89 
91 
96 
97 private:
99 #if defined(RCLCPP_HAS_SIGACTION)
100  using signal_handler_type = struct sigaction;
101 #else
102  using signal_handler_type = void (*)(int);
103 #endif
104 
105 
106  SignalHandler() = default;
107 
108  ~SignalHandler();
109 
110  SignalHandler(const SignalHandler &) = delete;
111  SignalHandler(SignalHandler &&) = delete;
112  SignalHandler &
113  operator=(const SignalHandler &) = delete;
114  SignalHandler &&
115  operator=(SignalHandler &&) = delete;
116 
118  void
119  signal_handler_common();
120 
121 #if defined(RCLCPP_HAS_SIGACTION)
123  static
124  void
125  signal_handler(int signal_value, siginfo_t * siginfo, void * context);
126 #else
128  static
129  void
130  signal_handler(int signal_value);
131 #endif
132 
134  void
135  deferred_signal_handler();
136 
138 
142  void
143  setup_wait_for_signal();
144 
146 
151  void
152  teardown_wait_for_signal() noexcept;
153 
155 
160  void
161  wait_for_signal();
162 
164 
170  void
171  notify_signal_handler() noexcept;
172 
173  static
174  signal_handler_type
175  set_signal_handler(
176  int signal_value,
177  const signal_handler_type & signal_handler);
178 
179  signal_handler_type
180  get_old_signal_handler(int signum);
181 
183 
184  signal_handler_type old_sigint_handler_;
185  signal_handler_type old_sigterm_handler_;
186 
187  // logger instance
188  rclcpp::Logger logger_ = rclcpp::get_logger("rclcpp");
189 
190  // Whether or not a signal has been received.
191  std::atomic_bool signal_received_ = false;
192  // A thread to which signal handling tasks are deferred.
193  std::thread signal_handler_thread_;
194 
195  // A mutex used to synchronize the install() and uninstall() methods.
196  std::mutex install_mutex_;
197  // Whether or not the signal handler has been installed.
198  std::atomic_bool installed_ = false;
199 
200  // Whether or not the semaphore for wait_for_signal is setup.
201  std::atomic_bool wait_for_signal_is_setup_;
202  // Storage for the wait_for_signal semaphore.
203 #if defined(_WIN32)
204  HANDLE signal_handler_sem_;
205 #elif defined(__APPLE__)
206  dispatch_semaphore_t signal_handler_sem_;
207 #else // posix
208  sem_t signal_handler_sem_;
209 #endif
210 };
211 
212 } // namespace rclcpp
213 
214 #endif // RCLCPP__SIGNAL_HANDLER_HPP_
Responsible for managing the SIGINT/SIGTERM signal handling.
static rclcpp::Logger & get_logger()
Return a global singleton logger to avoid needing to create it everywhere.
bool is_installed()
Return true if installed, false otherwise.
static SignalHandler & get_global_signal_handler()
Return the global singleton of this class.
bool install(SignalHandlerOptions signal_handler_options=SignalHandlerOptions::All)
Install the signal handler for SIGINT/SIGTERM and start the dedicated signal handling thread.
rclcpp::SignalHandlerOptions get_current_signal_handler_options()
Get the current signal handler options.
Versions of rosidl_typesupport_cpp::get_message_type_support_handle that handle adapted types.
SignalHandlerOptions
Option to indicate which signal handlers rclcpp should install.
Definition: utilities.hpp:48
@ None
Do not install any signal handler.
@ All
Install both sigint and sigterm, this is the default behavior.
RCLCPP_PUBLIC Logger get_logger(const std::string &name)
Return a named logger.
Definition: logger.cpp:33