Caffe2 - C++ API
A deep learning, cross platform ML framework
signal_handler.cc
1 #include "caffe2/utils/signal_handler.h"
2 #include "caffe2/core/logging.h"
3 
4 #if defined(_MSC_VER)
5 
6 // Currently we do not support signal handling in Windows yet - below is a
7 // minimal implementation that makes things compile.
8 namespace caffe2 {
9 SignalHandler::SignalHandler(
10  SignalHandler::Action SIGINT_action,
11  SignalHandler::Action SIGHUP_action) {}
12 SignalHandler::~SignalHandler() {}
13 bool SignalHandler::GotSIGINT() {
14  return false;
15 }
16 bool SignalHandler::GotSIGHUP() {
17  return false;
18 }
19 SignalHandler::Action SignalHandler::CheckForSignals() {
20  return SignalHandler::Action::NONE;
21 }
22 } // namespace caffe2
23 
24 #else // defined(_MSC_VER)
25 
26 // Normal signal handler implementation.
27 
28 #include <atomic>
29 #include <signal.h>
30 #include <unordered_set>
31 
32 namespace {
33 
34  static struct sigaction previous_sighup;
35  static struct sigaction previous_sigint;
36  static volatile sig_atomic_t sigint_count = 0;
37  static volatile sig_atomic_t sighup_count = 0;
38  static std::atomic<int> hooked_up_count{0};
39 
40  void handle_signal(int signal) {
41  switch (signal) {
42  case SIGHUP:
43  sighup_count += 1;
44  if (previous_sighup.sa_handler) {
45  previous_sighup.sa_handler(signal);
46  }
47  break;
48  case SIGINT:
49  sigint_count += 1;
50  if (previous_sigint.sa_handler) {
51  previous_sigint.sa_handler(signal);
52  }
53  break;
54  }
55  }
56 
57  void HookupHandler() {
58  if (hooked_up_count++) {
59  return;
60  }
61  struct sigaction sa;
62  // Setup the handler
63  sa.sa_handler = &handle_signal;
64  // Restart the system call, if at all possible
65  sa.sa_flags = SA_RESTART;
66  // Block every signal during the handler
67  sigfillset(&sa.sa_mask);
68  // Intercept SIGHUP and SIGINT
69  if (sigaction(SIGHUP, &sa, nullptr) == -1) {
70  LOG(FATAL) << "Cannot install SIGHUP handler.";
71  }
72  if (sigaction(SIGINT, &sa, nullptr) == -1) {
73  LOG(FATAL) << "Cannot install SIGINT handler.";
74  }
75  }
76 
77  // Set the signal handlers to the default.
78  void UnhookHandler() {
79  if (--hooked_up_count > 0) {
80  return;
81  }
82  struct sigaction sa;
83  // Setup the sighub handler
84  sa.sa_handler = SIG_DFL;
85  // Restart the system call, if at all possible
86  sa.sa_flags = SA_RESTART;
87  // Block every signal during the handler
88  sigfillset(&sa.sa_mask);
89  // Intercept SIGHUP and SIGINT
90  if (sigaction(SIGHUP, &sa, &previous_sighup) == -1) {
91  LOG(FATAL) << "Cannot uninstall SIGHUP handler.";
92  }
93  if (sigaction(SIGINT, &sa, &previous_sigint) == -1) {
94  LOG(FATAL) << "Cannot uninstall SIGINT handler.";
95  }
96  }
97 
98 } // namespace
99 
100 namespace caffe2 {
101 
102 SignalHandler::SignalHandler(SignalHandler::Action SIGINT_action,
103  SignalHandler::Action SIGHUP_action):
104  SIGINT_action_(SIGINT_action),
105  SIGHUP_action_(SIGHUP_action),
106  my_sigint_count_(sigint_count),
107  my_sighup_count_(sighup_count) {
108  HookupHandler();
109 }
110 
111 SignalHandler::~SignalHandler() {
112  UnhookHandler();
113 }
114 
115 // Return true iff a SIGINT has been received since the last time this
116 // function was called.
117 bool SignalHandler::GotSIGINT() {
118  uint64_t count = sigint_count;
119  bool result = (count != my_sigint_count_);
120  my_sigint_count_ = count;
121  return result;
122 }
123 
124 // Return true iff a SIGHUP has been received since the last time this
125 // function was called.
126 bool SignalHandler::GotSIGHUP() {
127  uint64_t count = sighup_count;
128  bool result = (count != my_sighup_count_);
129  my_sighup_count_ = count;
130  return result;
131 }
132 
133 
134 SignalHandler::Action SignalHandler::CheckForSignals() {
135  if (GotSIGHUP()) {
136  return SIGHUP_action_;
137  }
138  if (GotSIGINT()) {
139  return SIGINT_action_;
140  }
141  return SignalHandler::Action::NONE;
142 }
143 
144 } // namespace caffe2
145 
146 #endif // defined(_MSC_VER)
Simple registry implementation in Caffe2 that uses static variables to register object creators durin...