CMS 3D CMS Logo

UnixSignalHandlers.cc

Go to the documentation of this file.
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       // all blocked for now
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       // ignore all the RT signals
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       // reenable the signals
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       // enable the specified signal
00092       MUST_BE_ZERO(sigaddset(newset, signum));
00093     }
00094 
00095 
00096 //--------------------------------------------------------------
00097 
00098     void disableSignal( sigset_t* newset, const int signum )
00099     {
00100       // disable the specified signal
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       // set up my RT signal now
00122       struct sigaction act;
00123       memset(&act,0,sizeof(act));
00124       act.sa_sigaction = func;
00125       act.sa_flags = SA_RESTART;
00126       
00127       // get my signal number
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 //    Make a full house set of signals, except for SIGKILL = 9
00154 //    and SIGSTOP = 19 which cannot be blocked
00155       MUST_BE_ZERO(sigfillset(&tmpset));
00156       MUST_BE_ZERO(sigdelset(&tmpset, SIGKILL));
00157       MUST_BE_ZERO(sigdelset(&tmpset, SIGSTOP));
00158 //    Swap it with the current sigset_t
00159       MUST_BE_ZERO(pthread_sigmask( SIG_SETMASK, &tmpset, &oldset ));
00160 //    Now see what's included in the set
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 //    Finally put the original sigset_t back
00170       MUST_BE_ZERO(pthread_sigmask( SIG_SETMASK, &oldset, &tmpset));
00171     }
00172 
00173 } // end of namespace edm

Generated on Tue Jun 9 17:36:52 2009 for CMSSW by  doxygen 1.5.4