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

ArSignalHandler_LIN.cpp

00001 /*
00002 ActivMedia Robotics Interface for Applications (ARIA)
00003 Copyright (C) 2004,2005 ActivMedia Robotics, LLC
00004 
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 ActivMedia Robotics for information about a commercial version of ARIA at 
00022 robots@activmedia.com or 
00023 ActivMedia Robotics, 19 Columbia Drive, Amherst, NH 03031; 800-639-9481
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   //sigaddset(&commonSet, SigSEGV);
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   // I think the old code was broken in that it didn't block all the
00249   // signals it wanted to wait for, which sigwait is supposed to
00250   // do... it also didn't check the return... for some reason system
00251   // on a debian box (at least a newer one) causes sigwait to return
00252   // with an error state (return of 4)... the old sigwait from rh 7.x
00253   // said it never returned an error... I don't entirely understand
00254   // it, and thats why both blocks of code are here
00255 
00256   // old code
00257   /*
00258   int sig;
00259   
00260   pthread_sigmask(SIG_SETMASK, &ourBlockSigSet, 0);
00261 
00262   while (myRunning)
00263   {
00264     sigwait(&ourHandleSigSet, &sig);
00265     signalCB(sig);
00266   }
00267 
00268   return(0);
00269 */
00270   // new code
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   //ourSigMap[SIGSTKFLT]="SIGSTKFLT";
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 }

Generated on Wed Oct 19 12:56:37 2005 for Aria by  doxygen 1.4.0