00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 #include "ArExport.h"
00028 #include "ArSignalHandler.h"
00029 #include "ArLog.h"
00030 #include "ariaInternal.h"
00031 
00032 ArSignalHandler *ArSignalHandler::ourSignalHandler=0;
00033 ArStrMap ArSignalHandler::ourSigMap;
00034 sigset_t ArSignalHandler::ourBlockSigSet;
00035 sigset_t ArSignalHandler::ourHandleSigSet;
00036 std::list<ArFunctor1<int>*> ArSignalHandler::ourHandlerList;
00037 
00038 
00039 void ArSignalHandler::signalCB(int sig)
00040 {
00041   std::list<ArFunctor1<int>*>::iterator iter;
00042 
00043   ArLog::log(ArLog::Verbose,
00044              "ArSignalHandler::runThread: Received signal '%s' Number %d ",
00045              ourSigMap[sig].c_str(), sig);
00046   for (iter=ourHandlerList.begin(); iter != ourHandlerList.end(); ++iter)
00047     (*iter)->invoke(sig);
00048   if (ourHandlerList.begin() == ourHandlerList.end())
00049     ArLog::log(ArLog::Terse,
00050   "ArSignalHandler::runThread: No handler function. Unhandled signal '%s' Number %d", 
00051                ourSigMap[sig].c_str(), sig);
00052 }  
00053 
00060 void ArSignalHandler::createHandlerNonThreaded()
00061 {
00062   int i;
00063   initSigMap();
00064   signal(SigSEGV, &signalCB);
00065   signal(SigFPE, &signalCB);
00066   for (i=1; i <= SigPWR; ++i)
00067   {
00068     if (sigismember(&ourBlockSigSet, i))
00069       signal(i, SIG_IGN);
00070     if (sigismember(&ourHandleSigSet, i))
00071       signal(i, &signalCB);
00072   }
00073   
00074 }
00075 
00086 void ArSignalHandler::createHandlerThreaded()
00087 {
00088   signal(SigSEGV, &signalCB);
00089   signal(SigFPE, &signalCB);
00090   getHandler()->create(false);
00091 }
00092 
00099 void ArSignalHandler::blockCommon()
00100 {
00101   unblockAll();
00102   block(SigHUP);
00103   block(SigPIPE);
00104   block(SigINT);
00105   block(SigQUIT);
00106   block(SigTERM);
00107 }
00108 
00113 void ArSignalHandler::unblockAll()
00114 {
00115   sigemptyset(&ourBlockSigSet);
00116 }
00117 
00123 void ArSignalHandler::block(Signal sig)
00124 {
00125   sigaddset(&ourBlockSigSet, sig);
00126 }
00127 
00133 void ArSignalHandler::unblock(Signal sig)
00134 {
00135   sigdelset(&ourBlockSigSet, sig);
00136 }
00137 
00144 void ArSignalHandler::handle(Signal sig)
00145 {
00146   unblock(sig);
00147   sigaddset(&ourHandleSigSet, sig);
00148 }
00149 
00155 void ArSignalHandler::unhandle(Signal sig)
00156 {
00157   sigdelset(&ourHandleSigSet, sig);
00158 }
00159 
00168 void ArSignalHandler::addHandlerCB(ArFunctor1<int> *func,
00169                                             ArListPos::Pos position)
00170 {
00171 
00172   if (position == ArListPos::FIRST)
00173     ourHandlerList.push_front(func);
00174   else if (position == ArListPos::LAST)
00175     ourHandlerList.push_back(func);
00176   else
00177     ArLog::log(ArLog::Terse, 
00178                "ArSignalHandler::addHandler: Invalid position.");
00179 }
00180 
00186 void ArSignalHandler::delHandlerCB(ArFunctor1<int> *func)
00187 {
00188   ourHandlerList.remove(func);
00189 }
00190 
00199 ArSignalHandler * ArSignalHandler::getHandler()
00200 {
00201   if (!ourSignalHandler)
00202     ourSignalHandler=new ArSignalHandler;
00203 
00204   return(ourSignalHandler);
00205 }
00206 
00212 void ArSignalHandler::blockCommonThisThread()
00213 {
00214   sigset_t commonSet;
00215   sigemptyset(&commonSet);
00216   sigaddset(&commonSet, SigHUP);
00217   sigaddset(&commonSet, SigPIPE);
00218   sigaddset(&commonSet, SigINT);
00219   sigaddset(&commonSet, SigQUIT);
00220   sigaddset(&commonSet, SigTERM);
00221   
00222   pthread_sigmask(SIG_SETMASK, &commonSet, 0);
00223 }
00224 
00225 void ArSignalHandler::blockAllThisThread()
00226 {
00227   sigset_t fullSet;
00228   sigfillset(&fullSet);
00229   pthread_sigmask(SIG_SETMASK, &fullSet, 0);
00230 }
00231 
00232 
00233 ArSignalHandler::ArSignalHandler() :
00234   ourIgnoreQUIT(false)
00235 {
00236   setThreadName("ArSignalHandler");
00237   initSigMap();
00238 }
00239 
00240 ArSignalHandler::~ArSignalHandler()
00241 {
00242 }
00243 
00244 void * ArSignalHandler::runThread(void *arg)
00245 {
00246   threadStarted();
00247 
00248   
00249   
00250   
00251   
00252   
00253   
00254   
00255 
00256   
00257   
00258 
00259 
00260 
00261 
00262 
00263 
00264 
00265 
00266 
00267 
00268 
00269 
00270   
00271   int sig = 0;
00272   
00273   while (myRunning)
00274   {
00275     pthread_sigmask(SIG_SETMASK, &ourBlockSigSet, 0);
00276     pthread_sigmask(SIG_BLOCK, &ourHandleSigSet, 0);
00277 
00278     if (sigwait(&ourHandleSigSet, &sig) == 0)
00279       signalCB(sig);
00280   }
00281   return(0);
00282 }
00283 
00284 void ArSignalHandler::initSigMap()
00285 {
00286   ourSigMap[SIGHUP]="SIGHUP";
00287   ourSigMap[SIGINT]="SIGINT";
00288   ourSigMap[SIGQUIT]="SIGQUIT";
00289   ourSigMap[SIGILL]="SIGILL";
00290   ourSigMap[SIGTRAP]="SIGTRAP";
00291   ourSigMap[SIGABRT]="SIGABRT";
00292 #ifdef linux
00293   ourSigMap[SIGIOT]="SIGIOT";
00294 #endif
00295   ourSigMap[SIGBUS]="SIGBUS";
00296   ourSigMap[SIGFPE]="SIGFPE";
00297   ourSigMap[SIGKILL]="SIGKILL";
00298   ourSigMap[SIGUSR1]="SIGUSR1";
00299   ourSigMap[SIGSEGV]="SIGSEGV";
00300   ourSigMap[SIGUSR2]="SIGUSR2";
00301   ourSigMap[SIGPIPE]="SIGPIPE";
00302   ourSigMap[SIGALRM]="SIGALRM";
00303   ourSigMap[SIGTERM]="SIGTERM";
00304   
00305   ourSigMap[SIGCHLD]="SIGCHLD";
00306   ourSigMap[SIGCONT]="SIGCONT";
00307   ourSigMap[SIGSTOP]="SIGSTOP";
00308   ourSigMap[SIGTSTP]="SIGTSTP";
00309   ourSigMap[SIGTTIN]="SIGTTIN";
00310   ourSigMap[SIGTTOU]="SIGTTOU";
00311   ourSigMap[SIGURG]="SIGURG";
00312   ourSigMap[SIGXCPU]="SIGXCPU";
00313   ourSigMap[SIGXFSZ]="SIGXFSZ";
00314   ourSigMap[SIGVTALRM]="SIGVTALRM";
00315   ourSigMap[SIGPROF]="SIGPROF";
00316   ourSigMap[SIGWINCH]="SIGWINCH";
00317   ourSigMap[SIGIO]="SIGIO";
00318 #ifdef linux
00319   ourSigMap[SIGPWR]="SIGPWR";
00320 #endif
00321 }
00322 
00323 const char *ArSignalHandler::nameSignal(int sig)
00324 {
00325   return(ourSigMap[sig].c_str());
00326 }
00327 
00328 void ArSignalHandler::logThread(void)
00329 {
00330   if (ourSignalHandler != NULL)
00331     ourSignalHandler->logThreadInfo();
00332   else
00333     ArLog::log(ArLog::Normal, "No signal handler thread running");
00334 }