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