00001 #include <iostream>
00002 #include <iomanip>
00003 #include <cstdlib>
00004
00005 #include "FWCore/Utilities/interface/UnixSignalHandlers.h"
00006 #include "FWCore/Utilities/interface/DebugMacros.h"
00007
00008 namespace edm {
00009
00010 boost::mutex usr2_lock;
00011
00012
00013
00014 volatile bool shutdown_flag = false;
00015
00016 extern "C" {
00017 void ep_sigusr2(int,siginfo_t*,void*)
00018 {
00019 FDEBUG(1) << "in sigusr2 handler\n";
00020 shutdown_flag = true;
00021 }
00022 }
00023
00024
00025
00026 boost::mutex signum_lock;
00027 volatile int signum_value =
00028 #if defined(__linux__)
00029 SIGRTMIN;
00030 #else
00031 0;
00032 #endif
00033
00034
00035
00036 int getSigNum()
00037 {
00038 boost::mutex::scoped_lock sl(signum_lock);
00039 int rc = signum_value;
00040 ++signum_value;
00041 return rc;
00042 }
00043
00044 #define MUST_BE_ZERO(fun) if((fun) != 0) \
00045 { perror("UnixSignalHandlers::setupSignal: sig function failed"); abort(); }
00046
00047
00048
00049 void disableAllSigs( sigset_t* oldset )
00050 {
00051 sigset_t myset;
00052
00053 MUST_BE_ZERO(sigfillset(&myset));
00054 MUST_BE_ZERO(pthread_sigmask(SIG_SETMASK,&myset,oldset));
00055 }
00056
00057
00058
00059 void disableRTSigs()
00060 {
00061 #if defined(__linux__)
00062
00063 sigset_t myset;
00064 MUST_BE_ZERO(sigemptyset(&myset));
00065
00066 struct sigaction tmpact;
00067 memset(&tmpact,0,sizeof(tmpact));
00068 tmpact.sa_handler = SIG_IGN;
00069
00070 for(int num = SIGRTMIN; num < SIGRTMAX; ++num) {
00071 MUST_BE_ZERO(sigaddset(&myset,num));
00072 MUST_BE_ZERO(sigaction(num,&tmpact,NULL));
00073 }
00074
00075 MUST_BE_ZERO(pthread_sigmask(SIG_BLOCK,&myset,0));
00076 #endif
00077 }
00078
00079
00080
00081 void reenableSigs( sigset_t* oldset )
00082 {
00083
00084 MUST_BE_ZERO(pthread_sigmask(SIG_SETMASK,oldset,0));
00085 }
00086
00087
00088
00089 void enableSignal( sigset_t* newset, const int signum )
00090 {
00091
00092 MUST_BE_ZERO(sigaddset(newset, signum));
00093 }
00094
00095
00096
00097
00098 void disableSignal( sigset_t* newset, const int signum )
00099 {
00100
00101 MUST_BE_ZERO(sigdelset(newset, signum));
00102 }
00103
00104
00105
00106 void installCustomHandler( const int signum, CFUNC func )
00107 {
00108 sigset_t oldset;
00109 edm::disableAllSigs(&oldset);
00110 #if defined(__linux__)
00111 edm::disableRTSigs();
00112 #endif
00113 edm::installSig(signum,edm::ep_sigusr2);
00114 edm::reenableSigs(&oldset);
00115 }
00116
00117
00118
00119 void installSig( const int signum, CFUNC func )
00120 {
00121
00122 struct sigaction act;
00123 memset(&act,0,sizeof(act));
00124 act.sa_sigaction = func;
00125 act.sa_flags = SA_RESTART;
00126
00127
00128 int mysig = signum;
00129 if( mysig == SIGKILL ) {
00130 perror("Cannot install handler for KILL signal");
00131 return;
00132 } else if( mysig == SIGSTOP ) {
00133 perror("Cannot install handler for STOP signal");
00134 return;
00135 }
00136
00137 if(sigaction(mysig,&act,NULL) != 0) {
00138 perror("sigaction failed");
00139 abort();
00140 }
00141
00142 sigset_t newset;
00143 MUST_BE_ZERO(sigemptyset(&newset));
00144 MUST_BE_ZERO(sigaddset(&newset,mysig));
00145 MUST_BE_ZERO(pthread_sigmask(SIG_UNBLOCK,&newset,0));
00146 }
00147
00148
00149
00150 void sigInventory()
00151 {
00152 sigset_t tmpset, oldset;
00153
00154
00155 MUST_BE_ZERO(sigfillset(&tmpset));
00156 MUST_BE_ZERO(sigdelset(&tmpset, SIGKILL));
00157 MUST_BE_ZERO(sigdelset(&tmpset, SIGSTOP));
00158
00159 MUST_BE_ZERO(pthread_sigmask( SIG_SETMASK, &tmpset, &oldset ));
00160
00161 for(int k=1; k<_NSIG; ++k) {
00162 std::cerr << "sigismember is " << sigismember( &tmpset, k )
00163 << " for signal " << std::setw(2) << k
00164 #if defined(__linux__)
00165 << " (" << strsignal(k) << ")"
00166 #endif
00167 << std::endl;
00168 }
00169
00170 MUST_BE_ZERO(pthread_sigmask( SIG_SETMASK, &oldset, &tmpset));
00171 }
00172
00173 }