CMS 3D CMS Logo

UnixSignalHandlers.cc
Go to the documentation of this file.
1 #include <iostream>
2 #include <iomanip>
3 #include <cstdlib>
4 #include <cstdio>
5 #include <cstring>
6 
9 
10 #if !defined(NSIG)
11 #if defined(_NSIG)
12 #define NSIG _NSIG
13 #elif defined(__DARWIN_NSIG)
14 #define NSIG __DARWIN_NSIG
15 #endif
16 #endif
17 
18 namespace edm {
19 
20 //--------------------------------------------------------------
21 
22  volatile std::atomic<bool> shutdown_flag{false};
23 
24  extern "C" {
25  void ep_sigusr2(int,siginfo_t*,void*)
26  {
27  FDEBUG(1) << "in sigusr2 handler\n";
28  shutdown_flag.store(true);
29  }
30  }
31 #define MUST_BE_ZERO(fun) if((fun) != 0) \
32 { perror("UnixSignalHandlers::setupSignal: sig function failed"); abort(); }
33 
34 //--------------------------------------------------------------
35 
36  void disableAllSigs( sigset_t* oldset )
37  {
38  sigset_t myset;
39  // all blocked for now
40  MUST_BE_ZERO(sigfillset(&myset));
41  MUST_BE_ZERO(pthread_sigmask(SIG_SETMASK,&myset,oldset));
42  }
43 
44 //--------------------------------------------------------------
45 
47  {
48 #if defined(__linux__)
49  // ignore all the RT signals
50  sigset_t myset;
51  MUST_BE_ZERO(sigemptyset(&myset));
52 
53  struct sigaction tmpact;
54  memset(&tmpact,0,sizeof(tmpact));
55  tmpact.sa_handler = SIG_IGN;
56 
57  for(int num = SIGRTMIN; num <= SIGRTMAX; ++num) {
58  // signal 38 is used by Intel Amplifier
59  if( num == 38) continue;
60 
61 
62  MUST_BE_ZERO(sigaddset(&myset,num));
63  MUST_BE_ZERO(sigaction(num,&tmpact,nullptr));
64  }
65 
66  MUST_BE_ZERO(pthread_sigmask(SIG_BLOCK,&myset,nullptr));
67 #endif
68  }
69 
70 //--------------------------------------------------------------
71 
72  void reenableSigs( sigset_t* oldset )
73  {
74  // reenable the signals
75  MUST_BE_ZERO(pthread_sigmask(SIG_SETMASK,oldset,nullptr));
76  }
77 
78 //--------------------------------------------------------------
79 
80  void enableSignal( sigset_t* newset, const int signum )
81  {
82  // enable the specified signal
83  MUST_BE_ZERO(sigaddset(newset, signum));
84  }
85 
86 
87 //--------------------------------------------------------------
88 
89  void disableSignal( sigset_t* newset, const int signum )
90  {
91  // disable the specified signal
92  MUST_BE_ZERO(sigdelset(newset, signum));
93  }
94 
95 //--------------------------------------------------------------
96 
97  void installCustomHandler( const int signum, CFUNC func )
98  {
99  sigset_t oldset;
100  edm::disableAllSigs(&oldset);
101 #if defined(__linux__)
103 #endif
104  edm::installSig(signum,func);
105  edm::reenableSigs(&oldset);
106  }
107 
108 //--------------------------------------------------------------
109 
110  void installSig( const int signum, CFUNC func )
111  {
112  // set up my RT signal now
113  struct sigaction act;
114  memset(&act,0,sizeof(act));
115  act.sa_sigaction = func;
116  act.sa_flags = SA_RESTART;
117 
118  // get my signal number
119  int mysig = signum;
120  if( mysig == SIGKILL ) {
121  perror("Cannot install handler for KILL signal");
122  return;
123  } else if( mysig == SIGSTOP ) {
124  perror("Cannot install handler for STOP signal");
125  return;
126  }
127 
128  if(sigaction(mysig,&act,nullptr) != 0) {
129  perror("sigaction failed");
130  abort();
131  }
132 
133  sigset_t newset;
134  MUST_BE_ZERO(sigemptyset(&newset));
135  MUST_BE_ZERO(sigaddset(&newset,mysig));
136  MUST_BE_ZERO(pthread_sigmask(SIG_UNBLOCK,&newset,nullptr));
137  }
138 
139 //--------------------------------------------------------------
140 
142  {
143  sigset_t tmpset, oldset;
144 // Make a full house set of signals, except for SIGKILL = 9
145 // and SIGSTOP = 19 which cannot be blocked
146  MUST_BE_ZERO(sigfillset(&tmpset));
147  MUST_BE_ZERO(sigdelset(&tmpset, SIGKILL));
148  MUST_BE_ZERO(sigdelset(&tmpset, SIGSTOP));
149 // Swap it with the current sigset_t
150  MUST_BE_ZERO(pthread_sigmask( SIG_SETMASK, &tmpset, &oldset ));
151 // Now see what's included in the set
152  for(int k=1; k<NSIG; ++k) {
153  std::cerr << "sigismember is " << sigismember( &tmpset, k )
154  << " for signal " << std::setw(2) << k
155 #if defined(__linux__)
156  << " (" << strsignal(k) << ")"
157 #endif
158  << std::endl;
159  }
160 // Finally put the original sigset_t back
161  MUST_BE_ZERO(pthread_sigmask( SIG_SETMASK, &oldset, &tmpset));
162  }
163 
164 } // end of namespace edm
void installSig(int signum, CFUNC func)
void disableAllSigs(sigset_t *oldset)
volatile std::atomic< bool > shutdown_flag
void installCustomHandler(int signum, CFUNC func)
#define FDEBUG(lev)
Definition: DebugMacros.h:20
void enableSignal(sigset_t *newset, int signum)
void reenableSigs(sigset_t *oldset)
int k[5][pyjets_maxn]
void disableSignal(sigset_t *newset, int signum)
void sigInventory()
void(* CFUNC)(int, siginfo_t *, void *)
HLT enums.
void ep_sigusr2(int, siginfo_t *, void *)
#define MUST_BE_ZERO(fun)
void disableRTSigs()