Scarab  v2.4.8
Project 8 C++ Utility Library
signal_handler.cc
Go to the documentation of this file.
1 /*
2  * signal_handler.cc
3  *
4  * Created on: Dec 3, 2013
5  * Author: N.S. Oblath
6  */
7 
8 #define SCARAB_API_EXPORTS
9 
10 #include "signal_handler.hh"
11 
12 #include "cancelable.hh"
13 #include "error.hh"
14 #include "logger.hh"
15 
16 #include <signal.h>
17 #include <thread>
18 
19 #ifdef _WIN32
20 #include <Windows.h>
21 //#include "processthreadsapi.h"
22 #endif
23 
24 namespace scarab
25 {
26  LOGGER( slog, "signal_handler" );
27 
29 
32 
33  std::mutex signal_handler::f_mutex;
35 
37  {
38  // setup to handle SIGINT
39  if( ! f_handling_sig_int && signal( SIGINT, signal_handler::handler_cancel_threads ) == SIG_ERR )
40  {
41  throw error() << "Unable to handle SIGINT\n";
42  }
43  else
44  {
45  f_handling_sig_int = true;
46  }
47 
48 #ifndef _WIN32
49  // setup to handle SIGQUIT
50  if( ! f_handling_sig_quit && signal( SIGQUIT, signal_handler::handler_cancel_threads ) == SIG_ERR )
51  {
52  throw error() << "Unable to handle SIGQUIT\n";
53  }
54  else
55  {
56  f_handling_sig_quit = true;
57  }
58 
59  if( signal(SIGPIPE, SIG_IGN) == SIG_ERR )
60  {
61  throw error() << "Unable to ignore SIGPIPE\n";
62  }
63 #endif
64  }
65 
67  {
68  }
69 
71  {
72  f_mutex.lock();
73  f_cancelers.insert( a_cancelable );
74  f_mutex.unlock();
75  return;
76  }
77 
79  {
80  f_mutex.lock();
81  f_cancelers.erase( a_cancelable );
82  f_mutex.unlock();
83  return;
84  }
85 
87  {
88  f_mutex.lock();
89  f_got_exit_signal = false;
90  f_handling_sig_int = false;
91  f_handling_sig_quit = false;
92  f_cancelers.clear();
93  f_mutex.unlock();
94  return;
95  }
96 
98  {
99  return f_got_exit_signal;
100  }
101 
103  {
104  LPROG( slog, "\n\nHello! Your signal is being handled by signal_handler.\n"
105  << "Have a nice day!\n" );
107  return;
108  }
109 
110  void signal_handler::cancel_all( int a_code )
111  {
112  LDEBUG( slog, "Canceling all cancelables" );
113 
114  f_mutex.lock();
115  f_got_exit_signal = true;
116  while( ! f_cancelers.empty() )
117  {
118  (*f_cancelers.begin())->cancel( a_code );
119  f_cancelers.erase( f_cancelers.begin() );
120  std::this_thread::sleep_for( std::chrono::seconds(1) );
121  }
122  f_mutex.unlock();
123 
124 #ifdef _WIN32
125  ExitProcess( a_code );
126 #endif
127 
128  return;
129  }
130 
131 } /* namespace scarab */
static bool f_handling_sig_int
#define RETURN_SUCCESS
Definition: macros.hh:12
LOGGER(mtlog, "authentication")
#define LPROG(...)
Definition: logger.hh:368
static bool f_got_exit_signal
Contains the logger class and macros, based on Kasper&#39;s KLogger class.
static std::mutex f_mutex
static void cancel_all(int a_code)
Asynchronous call to exit the process with the given exit code.
static bool got_exit_signal()
Check whether an exit signal has been received.
#define LDEBUG(...)
Definition: logger.hh:365
static void handler_cancel_threads(int _ignored)
Signal handler function.
static bool f_handling_sig_quit
static cancelers f_cancelers
void add_cancelable(cancelable *a_cancelable)
Add a cancelable object.
void remove_cancelable(cancelable *a_cancelable)
Remove a cancelable object.
void reset()
Remove all cancelables.
std::set< cancelable *> cancelers