Signal.cpp

Go to the documentation of this file.
00001 // Signal.cpp,v 4.62 2006/06/19 12:51:17 schmidt Exp
00002 
00003 #include "ace/Recursive_Thread_Mutex.h"
00004 #include "ace/Signal.h"
00005 #include "ace/Object_Manager.h"
00006 #include "ace/Log_Msg.h"
00007 #include "ace/Containers.h"
00008 #include "ace/Guard_T.h"
00009 
00010 #if !defined (__ACE_INLINE__)
00011 #include "ace/Signal.inl"
00012 #endif /* __ACE_INLINE__ */
00013 
00014 ACE_RCSID(ace, Signal, "Signal.cpp,v 4.62 2006/06/19 12:51:17 schmidt Exp")
00015 
00016 // Static definitions.
00017 
00018 #if defined (ACE_HAS_SIG_C_FUNC)
00019 
00020 extern "C" void
00021 ace_sig_handler_dispatch (int signum, siginfo_t *info, ucontext_t *context)
00022 {
00023   ACE_TRACE ("ace_sig_handler_dispatch");
00024   ACE_Sig_Handler::dispatch (signum, info, context);
00025 }
00026 
00027 #define ace_signal_handler_dispatcher ACE_SignalHandler(ace_sig_handler_dispatch)
00028 
00029 #if !defined (ACE_HAS_BROKEN_HPUX_TEMPLATES)
00030 extern "C" void
00031 ace_sig_handlers_dispatch (int signum, siginfo_t *info, ucontext_t *context)
00032 {
00033   ACE_TRACE ("ace_sig_handlers_dispatch");
00034   ACE_Sig_Handlers::dispatch (signum, info, context);
00035 }
00036 
00037 #define ace_signal_handlers_dispatcher ACE_SignalHandler(ace_sig_handlers_dispatch)
00038 #endif /* ACE_HAS_BROKEN_HPUX_TEMPLATES */
00039 
00040 #else
00041 #define ace_signal_handler_dispatcher ACE_SignalHandler(ACE_Sig_Handler::dispatch)
00042 
00043 #if !defined (ACE_HAS_BROKEN_HPUX_TEMPLATES)
00044 #define ace_signal_handlers_dispatcher ACE_SignalHandler(ACE_Sig_Handlers::dispatch)
00045 #endif /* ACE_HAS_BROKEN_HPUX_TEMPLATES */
00046 #endif /* ACE_HAS_SIG_C_FUNC */
00047 
00048 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00049 
00050 // Array of Event_Handlers that will handle the signals.
00051 ACE_Event_Handler *ACE_Sig_Handler::signal_handlers_[ACE_NSIG];
00052 
00053 // Remembers if a signal has occurred.
00054 sig_atomic_t ACE_Sig_Handler::sig_pending_ = 0;
00055 
00056 ACE_ALLOC_HOOK_DEFINE(ACE_Sig_Action)
00057 
00058 void
00059 ACE_Sig_Action::dump (void) const
00060 {
00061 #if defined (ACE_HAS_DUMP)
00062   ACE_TRACE ("ACE_Sig_Action::dump");
00063 #endif /* ACE_HAS_DUMP */
00064 }
00065 
00066 ACE_ALLOC_HOOK_DEFINE(ACE_Sig_Set)
00067 
00068 ACE_Sig_Set::~ACE_Sig_Set (void)
00069 {
00070   ACE_TRACE ("ACE_Sig_Set::~ACE_Sig_Set");
00071   ACE_OS::sigemptyset (&this->sigset_);
00072 }
00073 
00074 ACE_Sig_Action::~ACE_Sig_Action (void)
00075 {
00076   ACE_TRACE ("ACE_Sig_Action::~ACE_Sig_Action");
00077 }
00078 
00079 // Restore the signal mask.
00080 
00081 ACE_Sig_Guard::~ACE_Sig_Guard (void)
00082 {
00083   //ACE_TRACE ("ACE_Sig_Guard::~ACE_Sig_Guard");
00084   if (!this->condition_)
00085     return;
00086 
00087 #if !defined (ACE_LACKS_UNIX_SIGNALS)
00088 #if defined (ACE_LACKS_PTHREAD_THR_SIGSETMASK)
00089   ACE_OS::sigprocmask (SIG_SETMASK,
00090                        (sigset_t *) this->omask_,
00091                        0);
00092 #else
00093   ACE_OS::thr_sigsetmask (SIG_SETMASK,
00094                           (sigset_t *) this->omask_,
00095                           0);
00096 #endif /* ACE_LACKS_PTHREAD_THR_SIGSETMASK */
00097 #endif /* !ACE_LACKS_UNIX_SIGNALS */
00098 }
00099 
00100 void
00101 ACE_Sig_Set::dump (void) const
00102 {
00103 #if defined (ACE_HAS_DUMP)
00104   ACE_TRACE ("ACE_Sig_Set::dump");
00105 #endif /* ACE_HAS_DUMP */
00106 }
00107 
00108 ACE_ALLOC_HOOK_DEFINE(ACE_Sig_Guard)
00109 
00110 void
00111 ACE_Sig_Guard::dump (void) const
00112 {
00113 #if defined (ACE_HAS_DUMP)
00114   ACE_TRACE ("ACE_Sig_Guard::dump");
00115 #endif /* ACE_HAS_DUMP */
00116 }
00117 
00118 ACE_Sig_Action::ACE_Sig_Action (void)
00119 {
00120   // ACE_TRACE ("ACE_Sig_Action::ACE_Sig_Action");
00121   this->sa_.sa_flags = 0;
00122 
00123   // Since Service_Config::signal_handler_ is static and has an
00124   // ACE_Sig_Action instance, Win32 will get errno set unless this is
00125   // commented out.
00126 #if !defined (ACE_WIN32)
00127   ACE_OS::sigemptyset (&this->sa_.sa_mask);
00128 #endif /* ACE_WIN32 */
00129   this->sa_.sa_handler = 0;
00130 }
00131 
00132 ACE_Sig_Action::ACE_Sig_Action (ACE_SignalHandler sig_handler,
00133                                 sigset_t *sig_mask,
00134                                 int sig_flags)
00135 {
00136   // ACE_TRACE ("ACE_Sig_Action::ACE_Sig_Action");
00137   this->sa_.sa_flags = sig_flags;
00138 
00139   if (sig_mask == 0)
00140     ACE_OS::sigemptyset (&this->sa_.sa_mask);
00141   else
00142     this->sa_.sa_mask = *sig_mask; // Structure assignment...
00143 
00144 #if !defined(ACE_HAS_TANDEM_SIGNALS)
00145   this->sa_.sa_handler = ACE_SignalHandlerV (sig_handler);
00146 #else
00147   this->sa_.sa_handler = (void (*)()) ACE_SignalHandlerV (sig_handler);
00148 #endif /* !ACE_HAS_TANDEM_SIGNALS */
00149 }
00150 
00151 ACE_Sig_Action::ACE_Sig_Action (ACE_SignalHandler sig_handler,
00152                                 const ACE_Sig_Set &sig_mask,
00153                                 int sig_flags)
00154 {
00155   // ACE_TRACE ("ACE_Sig_Action::ACE_Sig_Action");
00156   this->sa_.sa_flags = sig_flags;
00157 
00158   // Structure assignment...
00159   this->sa_.sa_mask = sig_mask.sigset ();
00160 
00161 #if !defined(ACE_HAS_TANDEM_SIGNALS)
00162   this->sa_.sa_handler = ACE_SignalHandlerV (sig_handler);
00163 #else
00164   this->sa_.sa_handler = (void (*)()) ACE_SignalHandlerV (sig_handler);
00165 #endif /* !ACE_HAS_TANDEM_SIGNALS */
00166 }
00167 
00168 ACE_Sig_Action::ACE_Sig_Action (ACE_SignalHandler sig_handler,
00169                                 int signum,
00170                                 sigset_t *sig_mask,
00171                                 int sig_flags)
00172 {
00173   // ACE_TRACE ("ACE_Sig_Action::ACE_Sig_Action");
00174   this->sa_.sa_flags = sig_flags;
00175 
00176   if (sig_mask == 0)
00177     ACE_OS::sigemptyset (&this->sa_.sa_mask);
00178   else
00179     this->sa_.sa_mask = *sig_mask; // Structure assignment...
00180 
00181 #if !defined(ACE_HAS_TANDEM_SIGNALS)
00182   this->sa_.sa_handler = ACE_SignalHandlerV (sig_handler);
00183 #else
00184   this->sa_.sa_handler = (void (*)()) ACE_SignalHandlerV (sig_handler);
00185 #endif /* !ACE_HAS_TANDEM_SIGNALS */
00186   ACE_OS::sigaction (signum, &this->sa_, 0);
00187 }
00188 
00189 ACE_Sig_Action::ACE_Sig_Action (ACE_SignalHandler sig_handler,
00190                                 int signum,
00191                                 const ACE_Sig_Set &sig_mask,
00192                                 int sig_flags)
00193 {
00194   // ACE_TRACE ("ACE_Sig_Action::ACE_Sig_Action");
00195   this->sa_.sa_flags = sig_flags;
00196 
00197   // Structure assignment...
00198   this->sa_.sa_mask = sig_mask.sigset ();
00199 
00200 #if !defined(ACE_HAS_TANDEM_SIGNALS)
00201   this->sa_.sa_handler = ACE_SignalHandlerV (sig_handler);
00202 #else
00203   this->sa_.sa_handler = (void (*)()) ACE_SignalHandlerV (sig_handler);
00204 #endif /* !ACE_HAS_TANDEM_SIGNALS */
00205   ACE_OS::sigaction (signum, &this->sa_, 0);
00206 }
00207 
00208 ACE_Sig_Action::ACE_Sig_Action (const ACE_Sig_Set &signals,
00209                                 ACE_SignalHandler sig_handler,
00210                                 const ACE_Sig_Set &sig_mask,
00211                                 int sig_flags)
00212 {
00213   // ACE_TRACE ("ACE_Sig_Action::ACE_Sig_Action");
00214   this->sa_.sa_flags = sig_flags;
00215 
00216   // Structure assignment...
00217   this->sa_.sa_mask = sig_mask.sigset ();
00218 
00219 #if !defined(ACE_HAS_TANDEM_SIGNALS)
00220   this->sa_.sa_handler = ACE_SignalHandlerV (sig_handler);
00221 #else
00222   this->sa_.sa_handler = (void (*)()) ACE_SignalHandlerV (sig_handler);
00223 #endif /* !ACE_HAS_TANDEM_SIGNALS */
00224 
00225 #if (ACE_NSIG > 0)
00226   for (int s = 1; s < ACE_NSIG; s++)
00227     if ((signals.is_member (s)) == 1)
00228       ACE_OS::sigaction (s, &this->sa_, 0);
00229 #else  /* ACE_NSIG <= 0  */
00230   ACE_UNUSED_ARG (signals);
00231 #endif /* ACE_NSIG <= 0  */
00232 }
00233 
00234 ACE_Sig_Action::ACE_Sig_Action (const ACE_Sig_Set &signals,
00235                                 ACE_SignalHandler sig_handler,
00236                                 sigset_t *sig_mask,
00237                                 int sig_flags)
00238 {
00239   // ACE_TRACE ("ACE_Sig_Action::ACE_Sig_Action");
00240   this->sa_.sa_flags = sig_flags;
00241 
00242   if (sig_mask == 0)
00243     ACE_OS::sigemptyset (&this->sa_.sa_mask);
00244   else
00245     this->sa_.sa_mask = *sig_mask; // Structure assignment...
00246 
00247 #if !defined(ACE_HAS_TANDEM_SIGNALS)
00248   this->sa_.sa_handler = ACE_SignalHandlerV (sig_handler);
00249 #else
00250   this->sa_.sa_handler = (void (*)()) ACE_SignalHandlerV (sig_handler);
00251 #endif /* !ACE_HAS_TANDEM_SIGNALS */
00252 
00253 #if (ACE_NSIG > 0)
00254   for (int s = 1; s < ACE_NSIG; s++)
00255     if ((signals.is_member (s)) == 1)
00256       ACE_OS::sigaction (s, &this->sa_, 0);
00257 #else  /* ACE_NSIG <= 0  */
00258   ACE_UNUSED_ARG (signals);
00259 #endif /* ACE_NSIG <= 0  */
00260 }
00261 
00262 ACE_ALLOC_HOOK_DEFINE(ACE_Sig_Handler)
00263 
00264 ACE_Sig_Handler::~ACE_Sig_Handler (void)
00265 {
00266 }
00267 
00268 void
00269 ACE_Sig_Handler::dump (void) const
00270 {
00271 #if defined (ACE_HAS_DUMP)
00272   ACE_TRACE ("ACE_Sig_Handler::dump");
00273 #endif /* ACE_HAS_DUMP */
00274 }
00275 
00276 int
00277 ACE_Sig_Handler::sig_pending (void)
00278 {
00279   ACE_TRACE ("ACE_Sig_Handler::sig_pending");
00280   ACE_MT (ACE_Recursive_Thread_Mutex *lock =
00281           ACE_Managed_Object<ACE_Recursive_Thread_Mutex>::get_preallocated_object
00282           (ACE_Object_Manager::ACE_SIG_HANDLER_LOCK);
00283           ACE_Guard<ACE_Recursive_Thread_Mutex> m (*lock));
00284   return ACE_Sig_Handler::sig_pending_ != 0;
00285 }
00286 
00287 void
00288 ACE_Sig_Handler::sig_pending (int pending)
00289 {
00290   ACE_TRACE ("ACE_Sig_Handler::sig_pending");
00291 
00292   ACE_MT (ACE_Recursive_Thread_Mutex *lock =
00293           ACE_Managed_Object<ACE_Recursive_Thread_Mutex>::get_preallocated_object
00294           (ACE_Object_Manager::ACE_SIG_HANDLER_LOCK);
00295           ACE_Guard<ACE_Recursive_Thread_Mutex> m (*lock));
00296   ACE_Sig_Handler::sig_pending_ = pending;
00297 }
00298 
00299 ACE_Event_Handler *
00300 ACE_Sig_Handler::handler (int signum)
00301 {
00302   ACE_TRACE ("ACE_Sig_Handler::handler");
00303   ACE_MT (ACE_Recursive_Thread_Mutex *lock =
00304     ACE_Managed_Object<ACE_Recursive_Thread_Mutex>::get_preallocated_object
00305       (ACE_Object_Manager::ACE_SIG_HANDLER_LOCK);
00306     ACE_Guard<ACE_Recursive_Thread_Mutex> m (*lock));
00307 
00308   if (ACE_Sig_Handler::in_range (signum))
00309     return ACE_Sig_Handler::signal_handlers_[signum];
00310   else
00311     return 0;
00312 }
00313 
00314 ACE_Event_Handler *
00315 ACE_Sig_Handler::handler_i (int signum,
00316                             ACE_Event_Handler *new_sh)
00317 {
00318   ACE_TRACE ("ACE_Sig_Handler::handler_i");
00319 
00320   if (ACE_Sig_Handler::in_range (signum))
00321     {
00322       ACE_Event_Handler *sh = ACE_Sig_Handler::signal_handlers_[signum];
00323 
00324       ACE_Sig_Handler::signal_handlers_[signum] = new_sh;
00325       return sh;
00326     }
00327   else
00328     return 0;
00329 }
00330 
00331 ACE_Event_Handler *
00332 ACE_Sig_Handler::handler (int signum,
00333                           ACE_Event_Handler *new_sh)
00334 {
00335   ACE_TRACE ("ACE_Sig_Handler::handler");
00336   ACE_MT (ACE_Recursive_Thread_Mutex *lock =
00337     ACE_Managed_Object<ACE_Recursive_Thread_Mutex>::get_preallocated_object
00338       (ACE_Object_Manager::ACE_SIG_HANDLER_LOCK);
00339     ACE_Guard<ACE_Recursive_Thread_Mutex> m (*lock));
00340 
00341   return ACE_Sig_Handler::handler_i (signum, new_sh);
00342 }
00343 
00344 // Register an ACE_Event_Handler along with the corresponding SIGNUM.
00345 // This method does NOT acquire any locks, so it can be called from a
00346 // signal handler.
00347 
00348 int
00349 ACE_Sig_Handler::register_handler_i (int signum,
00350                                      ACE_Event_Handler *new_sh,
00351                                      ACE_Sig_Action *new_disp,
00352                                      ACE_Event_Handler **old_sh,
00353                                      ACE_Sig_Action *old_disp)
00354 {
00355   ACE_TRACE ("ACE_Sig_Handler::register_handler_i");
00356 
00357   if (ACE_Sig_Handler::in_range (signum))
00358     {
00359       ACE_Sig_Action sa; // Define a "null" action.
00360       ACE_Event_Handler *sh = ACE_Sig_Handler::handler_i (signum,
00361                                                           new_sh);
00362 
00363       // Return a pointer to the old <ACE_Sig_Handler> if the user
00364       // asks for this.
00365       if (old_sh != 0)
00366         *old_sh = sh;
00367 
00368       // Make sure that <new_disp> points to a valid location if the
00369       // user doesn't care...
00370       if (new_disp == 0)
00371         new_disp = &sa;
00372 
00373       new_disp->handler (ace_signal_handler_dispatcher);
00374 #if !defined (ACE_HAS_LYNXOS_SIGNALS)
00375       new_disp->flags (new_disp->flags () | SA_SIGINFO);
00376 #endif /* ACE_HAS_LYNXOS_SIGNALS */
00377       return new_disp->register_action (signum, old_disp);
00378     }
00379   else
00380     return -1;
00381 }
00382 
00383 // Register an ACE_Event_Handler along with the corresponding SIGNUM.
00384 // This method acquires a lock, so it can't be called from a signal
00385 // handler, e.g., <dispatch>.
00386 
00387 int
00388 ACE_Sig_Handler::register_handler (int signum,
00389                                    ACE_Event_Handler *new_sh,
00390                                    ACE_Sig_Action *new_disp,
00391                                    ACE_Event_Handler **old_sh,
00392                                    ACE_Sig_Action *old_disp)
00393 {
00394   ACE_TRACE ("ACE_Sig_Handler::register_handler");
00395   ACE_MT (ACE_Recursive_Thread_Mutex *lock =
00396     ACE_Managed_Object<ACE_Recursive_Thread_Mutex>::get_preallocated_object
00397       (ACE_Object_Manager::ACE_SIG_HANDLER_LOCK);
00398     ACE_Guard<ACE_Recursive_Thread_Mutex> m (*lock));
00399 
00400   return ACE_Sig_Handler::register_handler_i (signum,
00401                                               new_sh,
00402                                               new_disp,
00403                                               old_sh,
00404                                               old_disp);
00405 }
00406 
00407 // Remove an ACE_Event_Handler.
00408 
00409 int
00410 ACE_Sig_Handler::remove_handler (int signum,
00411                                  ACE_Sig_Action *new_disp,
00412                                  ACE_Sig_Action *old_disp,
00413                                  int)
00414 {
00415   ACE_TRACE ("ACE_Sig_Handler::remove_handler");
00416   ACE_MT (ACE_Recursive_Thread_Mutex *lock =
00417     ACE_Managed_Object<ACE_Recursive_Thread_Mutex>::get_preallocated_object
00418       (ACE_Object_Manager::ACE_SIG_HANDLER_LOCK);
00419     ACE_Guard<ACE_Recursive_Thread_Mutex> m (*lock));
00420 
00421   if (ACE_Sig_Handler::in_range (signum))
00422     {
00423       ACE_Sig_Action sa (SIG_DFL, (sigset_t *) 0); // Define the default disposition.
00424 
00425       if (new_disp == 0)
00426         new_disp = &sa;
00427 
00428       ACE_Sig_Handler::signal_handlers_[signum] = 0;
00429 
00430       // Register either the new disposition or restore the default.
00431       return new_disp->register_action (signum, old_disp);
00432     }
00433 
00434     return -1;
00435 }
00436 
00437 // Master dispatcher function that gets called by a signal handler and
00438 // dispatches one handler...
00439 
00440 void
00441 ACE_Sig_Handler::dispatch (int signum,
00442                            siginfo_t *siginfo,
00443                            ucontext_t *ucontext)
00444 {
00445   ACE_TRACE ("ACE_Sig_Handler::dispatch");
00446 
00447   // Save/restore errno.
00448   ACE_Errno_Guard error (errno);
00449 
00450   // We can't use the <sig_pending> call here because that acquires
00451   // the lock, which is non-portable...
00452   ACE_Sig_Handler::sig_pending_ = 1;
00453 
00454   // Darn well better be in range since the OS dispatched this...
00455   ACE_ASSERT (ACE_Sig_Handler::in_range (signum));
00456 
00457   ACE_Event_Handler *eh = ACE_Sig_Handler::signal_handlers_[signum];
00458 
00459   if (eh != 0)
00460     {
00461       if (eh->handle_signal (signum, siginfo, ucontext) == -1)
00462         {
00463           // Define the default disposition.
00464           ACE_Sig_Action sa ((ACE_SignalHandler) SIG_DFL, (sigset_t *) 0);
00465 
00466           ACE_Sig_Handler::signal_handlers_[signum] = 0;
00467 
00468           // Remove the current disposition by registering the default
00469           // disposition.
00470           sa.register_action (signum);
00471 
00472           // Allow the event handler to close down if necessary.
00473           eh->handle_close (ACE_INVALID_HANDLE,
00474                             ACE_Event_Handler::SIGNAL_MASK);
00475         }
00476 #if defined (ACE_WIN32)
00477       else
00478         // Win32 is weird in the sense that it resets the signal
00479         // disposition to SIG_DFL after a signal handler is
00480         // dispatched.  Therefore, to workaround this "feature" we
00481         // must re-register the <ACE_Event_Handler> with <signum>
00482         // explicitly.
00483         ACE_Sig_Handler::register_handler_i (signum,
00484                                              eh);
00485 #endif /* ACE_WIN32*/
00486     }
00487 }
00488 
00489 ACE_Sig_Adapter::ACE_Sig_Adapter (ACE_Sig_Action &sa, int sigkey)
00490   : sigkey_ (sigkey),
00491     type_ (SIG_ACTION),
00492     sa_ (sa)
00493 {
00494   // ACE_TRACE ("ACE_Sig_Adapter::ACE_Sig_Adapter");
00495 }
00496 
00497 ACE_Sig_Adapter::ACE_Sig_Adapter (ACE_Event_Handler *eh,
00498                                   int sigkey)
00499   : sigkey_ (sigkey),
00500     type_ (ACE_HANDLER),
00501     eh_ (eh)
00502 {
00503   // ACE_TRACE ("ACE_Sig_Adapter::ACE_Sig_Adapter");
00504 }
00505 
00506 ACE_Sig_Adapter::ACE_Sig_Adapter (ACE_Sig_Handler_Ex sig_func,
00507                                   int sigkey)
00508   : sigkey_ (sigkey),
00509     type_ (C_FUNCTION),
00510     sig_func_ (sig_func)
00511 {
00512   // ACE_TRACE ("ACE_Sig_Adapter::ACE_Sig_Adapter");
00513 }
00514 
00515 ACE_Sig_Adapter::~ACE_Sig_Adapter ()
00516 {
00517 }
00518 
00519 int
00520 ACE_Sig_Adapter::sigkey (void)
00521 {
00522   ACE_TRACE ("ACE_Sig_Adapter::sigkey");
00523   return this->sigkey_;
00524 }
00525 
00526 int
00527 ACE_Sig_Adapter::handle_signal (int signum,
00528                                 siginfo_t *siginfo,
00529                                 ucontext_t *ucontext)
00530 {
00531   ACE_TRACE ("ACE_Sig_Adapter::handle_signal");
00532 
00533   switch (this->type_)
00534     {
00535     case SIG_ACTION:
00536       {
00537         // We have to dispatch a handler that was registered by a
00538         // third-party library.
00539 
00540         ACE_Sig_Action old_disp;
00541 
00542         // Make sure this handler executes in the context it was
00543         // expecting...
00544         this->sa_.register_action (signum, &old_disp);
00545 
00546         ACE_Sig_Handler_Ex sig_func = ACE_Sig_Handler_Ex (this->sa_.handler ());
00547 
00548         (*sig_func) (signum, siginfo, ucontext);
00549         // Restore the original disposition.
00550         old_disp.register_action (signum);
00551         break;
00552       }
00553     case ACE_HANDLER:
00554       this->eh_->handle_signal (signum, siginfo, ucontext);
00555       break;
00556     case C_FUNCTION:
00557       (*this->sig_func_) (signum, siginfo, ucontext);
00558       break;
00559     }
00560   return 0;
00561 }
00562 
00563 // ----------------------------------------
00564 // The following classes are local to this file.
00565 
00566 // There are bugs with HP/UX's C++ compiler that prevents this stuff
00567 // from compiling...
00568 #if !defined (ACE_HAS_BROKEN_HPUX_TEMPLATES)
00569 #define ACE_MAX_SIGNAL_HANDLERS ((size_t) 20)
00570 
00571 // Keeps track of the id that uniquely identifies each registered
00572 // signal handler.  This id can be used to cancel a timer via the
00573 // <remove_handler> method.
00574 int ACE_Sig_Handlers::sigkey_ = 0;
00575 
00576 // If this is > 0 then a 3rd party library has registered a
00577 // handler...
00578 int ACE_Sig_Handlers::third_party_sig_handler_ = 0;
00579 
00580 // Make life easier by defining typedefs...
00581 typedef ACE_Fixed_Set <ACE_Event_Handler *, ACE_MAX_SIGNAL_HANDLERS> ACE_SIG_HANDLERS_SET;
00582 typedef ACE_Fixed_Set_Iterator <ACE_Event_Handler *, ACE_MAX_SIGNAL_HANDLERS> ACE_SIG_HANDLERS_ITERATOR;
00583 
00584 class ACE_Sig_Handlers_Set
00585 {
00586 public:
00587   static ACE_SIG_HANDLERS_SET *instance (int signum);
00588 
00589 private:
00590   static ACE_SIG_HANDLERS_SET *sig_handlers_[ACE_NSIG];
00591 };
00592 
00593 /* static */
00594 ACE_SIG_HANDLERS_SET *ACE_Sig_Handlers_Set::sig_handlers_[ACE_NSIG];
00595 
00596 /* static */
00597 ACE_SIG_HANDLERS_SET *
00598 ACE_Sig_Handlers_Set::instance (int signum)
00599 {
00600   if (signum <= 0 || signum >= ACE_NSIG)
00601     return 0; // This will cause problems...
00602   else if (ACE_Sig_Handlers_Set::sig_handlers_[signum] == 0)
00603     ACE_NEW_RETURN (ACE_Sig_Handlers_Set::sig_handlers_[signum],
00604                     ACE_SIG_HANDLERS_SET,
00605                     0);
00606   return ACE_Sig_Handlers_Set::sig_handlers_[signum];
00607 }
00608 
00609 ACE_ALLOC_HOOK_DEFINE(ACE_Sig_Handlers)
00610 
00611 void
00612 ACE_Sig_Handlers::dump (void) const
00613 {
00614 #if defined (ACE_HAS_DUMP)
00615   ACE_TRACE ("ACE_Sig_Handlers::dump");
00616 #endif /* ACE_HAS_DUMP */
00617 }
00618 
00619 // This is the method that does all the dirty work...  The basic
00620 // structure of this method was devised by Detlef Becker.
00621 
00622 int
00623 ACE_Sig_Handlers::register_handler (int signum,
00624                                     ACE_Event_Handler *new_sh,
00625                                     ACE_Sig_Action *new_disp,
00626                                     ACE_Event_Handler **,
00627                                     ACE_Sig_Action *old_disp)
00628 {
00629   ACE_TRACE ("ACE_Sig_Handlers::register_handler");
00630   ACE_MT (ACE_Recursive_Thread_Mutex *lock =
00631     ACE_Managed_Object<ACE_Recursive_Thread_Mutex>::get_preallocated_object
00632       (ACE_Object_Manager::ACE_SIG_HANDLER_LOCK);
00633     ACE_Guard<ACE_Recursive_Thread_Mutex> m (*lock));
00634 
00635   if (ACE_Sig_Handler::in_range (signum))
00636     {
00637       ACE_Sig_Adapter *ace_sig_adapter = 0; // Our signal handler.
00638       ACE_Sig_Adapter *extern_sh = 0; // An external signal handler.
00639       ACE_Sig_Action sa;
00640 
00641       // Get current signal disposition.
00642       sa.retrieve_action (signum);
00643 
00644       // Check whether we are already in control of the signal
00645       // handling disposition...
00646 
00647       if (!(sa.handler () == ace_signal_handlers_dispatcher
00648           || sa.handler () == ACE_SignalHandler (SIG_IGN)
00649           || sa.handler () == ACE_SignalHandler (SIG_DFL)))
00650         {
00651           // Drat, a 3rd party library has already installed a signal ;-(
00652 
00653           // Upto here we never disabled RESTART_MODE.  Thus,
00654           // RESTART_MODE can only be changed by 3rd party libraries.
00655 
00656           if (ACE_BIT_DISABLED (sa.flags (), SA_RESTART)
00657               && ACE_Sig_Handlers::third_party_sig_handler_)
00658             // Toggling is disallowed since we might break 3rd party
00659             // code.
00660             return -1;
00661 
00662           // Note that we've seen a 3rd party handler...
00663           ACE_Sig_Handlers::third_party_sig_handler_ = 1;
00664 
00665           // Create a new 3rd party disposition, remembering its
00666           // preferred signal blocking etc...;
00667           ACE_NEW_RETURN (extern_sh,
00668                           ACE_Sig_Adapter (sa,
00669                                            ++ACE_Sig_Handlers::sigkey_),
00670                           -1);
00671           // Add the external signal handler to the set of handlers
00672           // for this signal.
00673           if (ACE_Sig_Handlers_Set::instance (signum)->insert (extern_sh) == -1)
00674             {
00675               delete extern_sh;
00676               return -1;
00677             }
00678         }
00679       // Add our new handler at this point.
00680       ACE_NEW_RETURN (ace_sig_adapter,
00681                       ACE_Sig_Adapter (new_sh,
00682                                        ++ACE_Sig_Handlers::sigkey_),
00683                       -1);
00684       // Add the ACE signal handler to the set of handlers for this
00685       // signal (make sure it goes before the external one if there is
00686       // one of these).
00687       if (ACE_Sig_Handlers_Set::instance (signum)->insert (ace_sig_adapter) == -1)
00688         {
00689           // We couldn't reinstall our handler, so let's pretend like
00690           // none of this happened...
00691           if (extern_sh)
00692             {
00693               ACE_Sig_Handlers_Set::instance (signum)->remove (extern_sh);
00694               delete extern_sh;
00695             }
00696           delete ace_sig_adapter;
00697           return -1;
00698         }
00699       // If ACE_Sig_Handlers::dispatch() was set we're done.
00700       else if (sa.handler () == ace_signal_handlers_dispatcher)
00701         return ace_sig_adapter->sigkey ();
00702 
00703       // Otherwise, we need to register our handler function so that
00704       // all signals will be dispatched through ACE.
00705       else
00706         {
00707           // Make sure that new_disp points to a valid location if the
00708           // user doesn't care...
00709           if (new_disp == 0)
00710             new_disp = &sa;
00711 
00712           new_disp->handler (ace_signal_handlers_dispatcher);
00713 
00714           // Default is to restart signal handlers.
00715           new_disp->flags (new_disp->flags () | SA_RESTART);
00716           new_disp->flags (new_disp->flags () | SA_SIGINFO);
00717 
00718           // Finally install (possibly reinstall) the ACE signal
00719           // handler disposition with the SA_RESTART mode enabled.
00720           if (new_disp->register_action (signum, old_disp) == -1)
00721             {
00722               // Yikes, lots of roll back at this point...
00723               ACE_Sig_Handlers_Set::instance (signum)->remove (ace_sig_adapter);
00724               delete ace_sig_adapter;
00725 
00726               if (extern_sh)
00727                 {
00728                   ACE_Sig_Handlers_Set::instance (signum)->remove (extern_sh);
00729                   delete extern_sh;
00730                 }
00731               return -1;
00732             }
00733           else // Return the signal key so that programs can cancel this
00734             // handler if they want!
00735             return ace_sig_adapter->sigkey ();
00736         }
00737     }
00738 
00739   return -1;
00740 }
00741 
00742 // Remove the ACE_Event_Handler currently associated with <signum>.
00743 // Install the new disposition (if given) and return the previous
00744 // disposition (if desired by the caller).  Returns 0 on success and
00745 // -1 if <signum> is invalid.
00746 
00747 int
00748 ACE_Sig_Handlers::remove_handler (int signum,
00749                                   ACE_Sig_Action *new_disp,
00750                                   ACE_Sig_Action *old_disp,
00751                                   int sigkey)
00752 {
00753   ACE_TRACE ("ACE_Sig_Handlers::remove_handler");
00754   ACE_MT (ACE_Recursive_Thread_Mutex *lock =
00755     ACE_Managed_Object<ACE_Recursive_Thread_Mutex>::get_preallocated_object
00756       (ACE_Object_Manager::ACE_SIG_HANDLER_LOCK);
00757     ACE_Guard<ACE_Recursive_Thread_Mutex> m (*lock));
00758 
00759   if (ACE_Sig_Handler::in_range (signum))
00760     {
00761       ACE_SIG_HANDLERS_SET *handler_set =
00762         ACE_Sig_Handlers_Set::instance (signum);
00763 
00764       ACE_SIG_HANDLERS_ITERATOR handler_iterator (*handler_set);
00765 
00766       // Iterate through the set of handlers for this signal.
00767 
00768       for (ACE_Event_Handler **eh;
00769            handler_iterator.next (eh) != 0;
00770            handler_iterator.advance ())
00771         {
00772           // Type-safe downcast would be nice here...
00773           ACE_Sig_Adapter *sh = (ACE_Sig_Adapter *) *eh;
00774 
00775           // Remove the handler if (1) its key matches the key we've
00776           // been told to remove or (2) if we've been told to remove
00777           // *all* handlers (i.e., <sigkey> == -1).
00778 
00779           if (sh->sigkey () == sigkey || sigkey == -1)
00780             {
00781               handler_set->remove (*eh);
00782               delete *eh;
00783             }
00784         }
00785 
00786       if (handler_set->size () == 0)
00787         {
00788           // If there are no more handlers left for a signal then
00789           // register the new disposition or restore the default
00790           // disposition.
00791 
00792           ACE_Sig_Action sa (SIG_DFL, (sigset_t *) 0);
00793 
00794           if (new_disp == 0)
00795             new_disp = &sa;
00796 
00797           return new_disp->register_action (signum, old_disp);
00798         }
00799       return 0;
00800     }
00801   else
00802     return -1;
00803 }
00804 
00805 // Master dispatcher function that gets called by a signal handler and
00806 // dispatches *all* the handlers...
00807 
00808 void
00809 ACE_Sig_Handlers::dispatch (int signum,
00810                             siginfo_t *siginfo,
00811                             ucontext_t *ucontext)
00812 {
00813   ACE_TRACE ("ACE_Sig_Handlers::dispatch");
00814   // The following is #ifdef'd out because it's entirely non-portable
00815   // to acquire a mutex in a signal handler...
00816 #if 0
00817   ACE_MT (ACE_Recursive_Thread_Mutex *lock =
00818     ACE_Managed_Object<ACE_Recursive_Thread_Mutex>::get_preallocated_object
00819       (ACE_Object_Manager::ACE_SIG_HANDLER_LOCK);
00820     ACE_TSS_Guard<ACE_Recursive_Thread_Mutex> m (*lock));
00821 #endif /* 0 */
00822 
00823   // Save/restore errno.
00824   ACE_Errno_Guard error (errno);
00825 
00826   ACE_Sig_Handler::sig_pending_ = 1;
00827 
00828   // Darn well better be in range since the OS dispatched this...
00829   ACE_ASSERT (ACE_Sig_Handler::in_range (signum));
00830 
00831   ACE_SIG_HANDLERS_SET *handler_set =
00832     ACE_Sig_Handlers_Set::instance (signum);
00833 
00834   ACE_SIG_HANDLERS_ITERATOR handler_iterator (*handler_set);
00835 
00836   for (ACE_Event_Handler **eh = 0;
00837        handler_iterator.next (eh) != 0;
00838        handler_iterator.advance ())
00839     {
00840       if ((*eh)->handle_signal (signum, siginfo, ucontext) == -1)
00841         {
00842           handler_set->remove (*eh);
00843           delete *eh;
00844         }
00845     }
00846 }
00847 
00848 // Return the first item in the list of handlers.  Note that this will
00849 // trivially provide the same behavior as the ACE_Sig_Handler
00850 // version if there is only 1 handler registered!
00851 
00852 ACE_Event_Handler *
00853 ACE_Sig_Handlers::handler (int signum)
00854 {
00855   ACE_TRACE ("ACE_Sig_Handlers::handler");
00856   ACE_SIG_HANDLERS_SET *handler_set =
00857     ACE_Sig_Handlers_Set::instance (signum);
00858   ACE_SIG_HANDLERS_ITERATOR handler_iterator (*handler_set);
00859   ACE_Event_Handler **eh = 0;
00860   handler_iterator.next (eh);
00861   return *eh;
00862 }
00863 
00864 // The following is a strange bit of logic that tries to give the same
00865 // semantics as what happens in ACE_Sig_Handler when we replace the
00866 // current signal handler with a new one.  Note that if there is only
00867 // one signal handler the behavior will be identical.  If there is
00868 // more than one handler then things get weird...
00869 
00870 ACE_Event_Handler *
00871 ACE_Sig_Handlers::handler (int signum, ACE_Event_Handler *new_sh)
00872 {
00873   ACE_TRACE ("ACE_Sig_Handlers::handler");
00874   ACE_SIG_HANDLERS_SET *handler_set =
00875     ACE_Sig_Handlers_Set::instance (signum);
00876   ACE_SIG_HANDLERS_ITERATOR handler_iterator (*handler_set);
00877   ACE_Event_Handler **eh = 0;
00878 
00879   // Find the first handler...
00880   handler_iterator.next (eh);
00881 
00882   // ... then remove it from the set ...
00883   handler_set->remove (*eh);
00884 
00885   // ... and then insert the new signal handler into the beginning of
00886   // the set (note, this is a bit too tied up in the implementation of
00887   // ACE_Unbounded_Set...).
00888   ACE_Sig_Adapter *temp;
00889 
00890   ACE_NEW_RETURN (temp,
00891                   ACE_Sig_Adapter (new_sh,
00892                                    ++ACE_Sig_Handlers::sigkey_),
00893                   0);
00894   handler_set->insert (temp);
00895   return *eh;
00896 }
00897 
00898 #endif /* ACE_HAS_BROKEN_HPUX_TEMPLATES */
00899 
00900 ACE_END_VERSIONED_NAMESPACE_DECL

Generated on Thu Nov 9 09:42:03 2006 for ACE by doxygen 1.3.6