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

Signal.cpp

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

Generated on Mon Jun 16 11:21:14 2003 for ACE by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002