CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
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 
21 
22 //--------------------------------------------------------------
23 
24  volatile bool shutdown_flag = false;
25 
26  extern "C" {
27  void ep_sigusr2(int,siginfo_t*,void*)
28  {
29  FDEBUG(1) << "in sigusr2 handler\n";
30  shutdown_flag = true;
31  }
32  }
33 
34 //--------------------------------------------------------------
35 
37  volatile int signum_value =
38 #if defined(__linux__)
39  SIGRTMIN;
40 #else
41  0;
42 #endif
43 
44 //--------------------------------------------------------------
45 
46  int getSigNum()
47  {
48  boost::mutex::scoped_lock sl(signum_lock);
49  int rc = signum_value;
50  ++signum_value;
51  return rc;
52  }
53 
54 #define MUST_BE_ZERO(fun) if((fun) != 0) \
55  { perror("UnixSignalHandlers::setupSignal: sig function failed"); abort(); }
56 
57 //--------------------------------------------------------------
58 
59  void disableAllSigs( sigset_t* oldset )
60  {
61  sigset_t myset;
62  // all blocked for now
63  MUST_BE_ZERO(sigfillset(&myset));
64  MUST_BE_ZERO(pthread_sigmask(SIG_SETMASK,&myset,oldset));
65  }
66 
67 //--------------------------------------------------------------
68 
70  {
71 #if defined(__linux__)
72  // ignore all the RT signals
73  sigset_t myset;
74  MUST_BE_ZERO(sigemptyset(&myset));
75 
76  struct sigaction tmpact;
77  memset(&tmpact,0,sizeof(tmpact));
78  tmpact.sa_handler = SIG_IGN;
79 
80  for(int num = SIGRTMIN; num < SIGRTMAX; ++num) {
81  MUST_BE_ZERO(sigaddset(&myset,num));
82  MUST_BE_ZERO(sigaction(num,&tmpact,NULL));
83  }
84 
85  MUST_BE_ZERO(pthread_sigmask(SIG_BLOCK,&myset,0));
86 #endif
87  }
88 
89 //--------------------------------------------------------------
90 
91  void reenableSigs( sigset_t* oldset )
92  {
93  // reenable the signals
94  MUST_BE_ZERO(pthread_sigmask(SIG_SETMASK,oldset,0));
95  }
96 
97 //--------------------------------------------------------------
98 
99  void enableSignal( sigset_t* newset, const int signum )
100  {
101  // enable the specified signal
102  MUST_BE_ZERO(sigaddset(newset, signum));
103  }
104 
105 
106 //--------------------------------------------------------------
107 
108  void disableSignal( sigset_t* newset, const int signum )
109  {
110  // disable the specified signal
111  MUST_BE_ZERO(sigdelset(newset, signum));
112  }
113 
114 //--------------------------------------------------------------
115 
116  void installCustomHandler( const int signum, CFUNC func )
117  {
118  sigset_t oldset;
119  edm::disableAllSigs(&oldset);
120 #if defined(__linux__)
122 #endif
123  edm::installSig(signum,func);
124  edm::reenableSigs(&oldset);
125  }
126 
127 //--------------------------------------------------------------
128 
129  void installSig( const int signum, CFUNC func )
130  {
131  // set up my RT signal now
132  struct sigaction act;
133  memset(&act,0,sizeof(act));
134  act.sa_sigaction = func;
135  act.sa_flags = SA_RESTART;
136 
137  // get my signal number
138  int mysig = signum;
139  if( mysig == SIGKILL ) {
140  perror("Cannot install handler for KILL signal");
141  return;
142  } else if( mysig == SIGSTOP ) {
143  perror("Cannot install handler for STOP signal");
144  return;
145  }
146 
147  if(sigaction(mysig,&act,NULL) != 0) {
148  perror("sigaction failed");
149  abort();
150  }
151 
152  sigset_t newset;
153  MUST_BE_ZERO(sigemptyset(&newset));
154  MUST_BE_ZERO(sigaddset(&newset,mysig));
155  MUST_BE_ZERO(pthread_sigmask(SIG_UNBLOCK,&newset,0));
156  }
157 
158 //--------------------------------------------------------------
159 
161  {
162  sigset_t tmpset, oldset;
163 // Make a full house set of signals, except for SIGKILL = 9
164 // and SIGSTOP = 19 which cannot be blocked
165  MUST_BE_ZERO(sigfillset(&tmpset));
166  MUST_BE_ZERO(sigdelset(&tmpset, SIGKILL));
167  MUST_BE_ZERO(sigdelset(&tmpset, SIGSTOP));
168 // Swap it with the current sigset_t
169  MUST_BE_ZERO(pthread_sigmask( SIG_SETMASK, &tmpset, &oldset ));
170 // Now see what's included in the set
171  for(int k=1; k<NSIG; ++k) {
172  std::cerr << "sigismember is " << sigismember( &tmpset, k )
173  << " for signal " << std::setw(2) << k
174 #if defined(__linux__)
175  << " (" << strsignal(k) << ")"
176 #endif
177  << std::endl;
178  }
179 // Finally put the original sigset_t back
180  MUST_BE_ZERO(pthread_sigmask( SIG_SETMASK, &oldset, &tmpset));
181  }
182 
183 } // end of namespace edm
void installSig(int signum, CFUNC func)
void disableAllSigs(sigset_t *oldset)
static boost::mutex mutex
Definition: LHEProxy.cc:11
int getSigNum()
#define NULL
Definition: scimark2.h:8
void installCustomHandler(int signum, CFUNC func)
#define FDEBUG(lev)
Definition: DebugMacros.h:18
void enableSignal(sigset_t *newset, int signum)
void reenableSigs(sigset_t *oldset)
int k[5][pyjets_maxn]
void disableSignal(sigset_t *newset, int signum)
boost::mutex signum_lock
long long int num
Definition: procUtils.cc:71
void sigInventory()
volatile int signum_value
void ep_sigusr2(int, siginfo_t *, void *)
volatile bool shutdown_flag
void(* CFUNC)(int, siginfo_t *, void *)
#define MUST_BE_ZERO(fun)
boost::mutex usr2_lock
void disableRTSigs()