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 }