Main Page | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | Related Pages | Examples

ArSignalHandler_LIN.cpp

00001 /*
00002 MobileRobots Advanced Robotics Interface for Applications (ARIA)
00003 Copyright (C) 2004, 2005 ActivMedia Robotics LLC
00004 Copyright (C) 2006, 2007 MobileRobots Inc.
00005 
00006      This program is free software; you can redistribute it and/or modify
00007      it under the terms of the GNU General Public License as published by
00008      the Free Software Foundation; either version 2 of the License, or
00009      (at your option) any later version.
00010 
00011      This program is distributed in the hope that it will be useful,
00012      but WITHOUT ANY WARRANTY; without even the implied warranty of
00013      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014      GNU General Public License for more details.
00015 
00016      You should have received a copy of the GNU General Public License
00017      along with this program; if not, write to the Free Software
00018      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019 
00020 If you wish to redistribute ARIA under different terms, contact 
00021 MobileRobots for information about a commercial version of ARIA at 
00022 robots@mobilerobots.com or 
00023 MobileRobots Inc, 19 Columbia Drive, Amherst, NH 03031; 800-639-9481
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   //sigaddset(&commonSet, SigSEGV);
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   // I think the old code was broken in that it didn't block all the
00256   // signals it wanted to wait for, which sigwait is supposed to
00257   // do... it also didn't check the return... for some reason system
00258   // on a debian box (at least a newer one) causes sigwait to return
00259   // with an error state (return of 4)... the old sigwait from rh 7.x
00260   // said it never returned an error... I don't entirely understand
00261   // it, and thats why both blocks of code are here
00262 
00263   // old code
00264   /*
00265   int sig;
00266   
00267   pthread_sigmask(SIG_SETMASK, &ourBlockSigSet, 0);
00268 
00269   while (myRunning)
00270   {
00271     sigwait(&ourHandleSigSet, &sig);
00272     signalCB(sig);
00273   }
00274 
00275   return(0);
00276 */
00277   // new code
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   //ourSigMap[SIGSTKFLT]="SIGSTKFLT";
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 }

Generated on Tue Feb 20 10:51:41 2007 for Aria by  doxygen 1.4.0