Sig_Handler.cpp

Go to the documentation of this file.
00001 // $Id: Sig_Handler.cpp 78423 2007-05-21 06:09:07Z olli $
00002 
00003 #include "ace/Sig_Handler.h"
00004 #include "ace/Sig_Adapter.h"
00005 #include "ace/Signal.h"
00006 #include "ace/Recursive_Thread_Mutex.h"
00007 #include "ace/Managed_Object.h"
00008 #include "ace/Containers.h"
00009 #include "ace/Guard_T.h"
00010 
00011 #if !defined (__ACE_INLINE__)
00012 #include "ace/Sig_Handler.inl"
00013 #endif /* __ACE_INLINE__ */
00014 
00015 ACE_RCSID(ace, Sig_Handler, "$Id: Sig_Handler.cpp 78423 2007-05-21 06:09:07Z olli $")
00016 
00017 #if defined (ACE_HAS_SIG_C_FUNC)
00018 
00019 extern "C" void
00020 ace_sig_handler_dispatch (int signum, siginfo_t *info, ucontext_t *context)
00021 {
00022   ACE_TRACE ("ace_sig_handler_dispatch");
00023   ACE_Sig_Handler::dispatch (signum, info, context);
00024 }
00025 
00026 #define ace_signal_handler_dispatcher ACE_SignalHandler(ace_sig_handler_dispatch)
00027 
00028 #if !defined (ACE_HAS_BROKEN_HPUX_TEMPLATES)
00029 extern "C" void
00030 ace_sig_handlers_dispatch (int signum, siginfo_t *info, ucontext_t *context)
00031 {
00032   ACE_TRACE ("ace_sig_handlers_dispatch");
00033   ACE_Sig_Handlers::dispatch (signum, info, context);
00034 }
00035 
00036 #define ace_signal_handlers_dispatcher ACE_SignalHandler(ace_sig_handlers_dispatch)
00037 #endif /* ACE_HAS_BROKEN_HPUX_TEMPLATES */
00038 
00039 #else
00040 #define ace_signal_handler_dispatcher ACE_SignalHandler(ACE_Sig_Handler::dispatch)
00041 
00042 #if !defined (ACE_HAS_BROKEN_HPUX_TEMPLATES)
00043 #define ace_signal_handlers_dispatcher ACE_SignalHandler(ACE_Sig_Handlers::dispatch)
00044 #endif /* ACE_HAS_BROKEN_HPUX_TEMPLATES */
00045 #endif /* ACE_HAS_SIG_C_FUNC */
00046 
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 
00057 ACE_ALLOC_HOOK_DEFINE(ACE_Sig_Handler)
00058 
00059 ACE_Sig_Handler::~ACE_Sig_Handler (void)
00060 {
00061 }
00062 
00063 void
00064 ACE_Sig_Handler::dump (void) const
00065 {
00066 #if defined (ACE_HAS_DUMP)
00067   ACE_TRACE ("ACE_Sig_Handler::dump");
00068 #endif /* ACE_HAS_DUMP */
00069 }
00070 
00071 int
00072 ACE_Sig_Handler::sig_pending (void)
00073 {
00074   ACE_TRACE ("ACE_Sig_Handler::sig_pending");
00075   ACE_MT (ACE_Recursive_Thread_Mutex *lock =
00076           ACE_Managed_Object<ACE_Recursive_Thread_Mutex>::get_preallocated_object
00077           (ACE_Object_Manager::ACE_SIG_HANDLER_LOCK);
00078           ACE_Guard<ACE_Recursive_Thread_Mutex> m (*lock));
00079   return ACE_Sig_Handler::sig_pending_ != 0;
00080 }
00081 
00082 void
00083 ACE_Sig_Handler::sig_pending (int pending)
00084 {
00085   ACE_TRACE ("ACE_Sig_Handler::sig_pending");
00086 
00087   ACE_MT (ACE_Recursive_Thread_Mutex *lock =
00088           ACE_Managed_Object<ACE_Recursive_Thread_Mutex>::get_preallocated_object
00089           (ACE_Object_Manager::ACE_SIG_HANDLER_LOCK);
00090           ACE_Guard<ACE_Recursive_Thread_Mutex> m (*lock));
00091   ACE_Sig_Handler::sig_pending_ = pending;
00092 }
00093 
00094 ACE_Event_Handler *
00095 ACE_Sig_Handler::handler (int signum)
00096 {
00097   ACE_TRACE ("ACE_Sig_Handler::handler");
00098   ACE_MT (ACE_Recursive_Thread_Mutex *lock =
00099     ACE_Managed_Object<ACE_Recursive_Thread_Mutex>::get_preallocated_object
00100       (ACE_Object_Manager::ACE_SIG_HANDLER_LOCK);
00101     ACE_Guard<ACE_Recursive_Thread_Mutex> m (*lock));
00102 
00103   if (ACE_Sig_Handler::in_range (signum))
00104     return ACE_Sig_Handler::signal_handlers_[signum];
00105   else
00106     return 0;
00107 }
00108 
00109 ACE_Event_Handler *
00110 ACE_Sig_Handler::handler_i (int signum,
00111                             ACE_Event_Handler *new_sh)
00112 {
00113   ACE_TRACE ("ACE_Sig_Handler::handler_i");
00114 
00115   if (ACE_Sig_Handler::in_range (signum))
00116     {
00117       ACE_Event_Handler *sh = ACE_Sig_Handler::signal_handlers_[signum];
00118 
00119       ACE_Sig_Handler::signal_handlers_[signum] = new_sh;
00120       return sh;
00121     }
00122   else
00123     return 0;
00124 }
00125 
00126 ACE_Event_Handler *
00127 ACE_Sig_Handler::handler (int signum,
00128                           ACE_Event_Handler *new_sh)
00129 {
00130   ACE_TRACE ("ACE_Sig_Handler::handler");
00131   ACE_MT (ACE_Recursive_Thread_Mutex *lock =
00132     ACE_Managed_Object<ACE_Recursive_Thread_Mutex>::get_preallocated_object
00133       (ACE_Object_Manager::ACE_SIG_HANDLER_LOCK);
00134     ACE_Guard<ACE_Recursive_Thread_Mutex> m (*lock));
00135 
00136   return ACE_Sig_Handler::handler_i (signum, new_sh);
00137 }
00138 
00139 // Register an ACE_Event_Handler along with the corresponding SIGNUM.
00140 // This method does NOT acquire any locks, so it can be called from a
00141 // signal handler.
00142 
00143 int
00144 ACE_Sig_Handler::register_handler_i (int signum,
00145                                      ACE_Event_Handler *new_sh,
00146                                      ACE_Sig_Action *new_disp,
00147                                      ACE_Event_Handler **old_sh,
00148                                      ACE_Sig_Action *old_disp)
00149 {
00150   ACE_TRACE ("ACE_Sig_Handler::register_handler_i");
00151 
00152   if (ACE_Sig_Handler::in_range (signum))
00153     {
00154       ACE_Sig_Action sa; // Define a "null" action.
00155       ACE_Event_Handler *sh = ACE_Sig_Handler::handler_i (signum,
00156                                                           new_sh);
00157 
00158       // Return a pointer to the old <ACE_Sig_Handler> if the user
00159       // asks for this.
00160       if (old_sh != 0)
00161         *old_sh = sh;
00162 
00163       // Make sure that <new_disp> points to a valid location if the
00164       // user doesn't care...
00165       if (new_disp == 0)
00166         new_disp = &sa;
00167 
00168       new_disp->handler (ace_signal_handler_dispatcher);
00169 #if !defined (ACE_HAS_LYNXOS_SIGNALS)
00170       new_disp->flags (new_disp->flags () | SA_SIGINFO);
00171 #endif /* ACE_HAS_LYNXOS_SIGNALS */
00172       return new_disp->register_action (signum, old_disp);
00173     }
00174   else
00175     return -1;
00176 }
00177 
00178 // Register an ACE_Event_Handler along with the corresponding SIGNUM.
00179 // This method acquires a lock, so it can't be called from a signal
00180 // handler, e.g., <dispatch>.
00181 
00182 int
00183 ACE_Sig_Handler::register_handler (int signum,
00184                                    ACE_Event_Handler *new_sh,
00185                                    ACE_Sig_Action *new_disp,
00186                                    ACE_Event_Handler **old_sh,
00187                                    ACE_Sig_Action *old_disp)
00188 {
00189   ACE_TRACE ("ACE_Sig_Handler::register_handler");
00190   ACE_MT (ACE_Recursive_Thread_Mutex *lock =
00191     ACE_Managed_Object<ACE_Recursive_Thread_Mutex>::get_preallocated_object
00192       (ACE_Object_Manager::ACE_SIG_HANDLER_LOCK);
00193     ACE_Guard<ACE_Recursive_Thread_Mutex> m (*lock));
00194 
00195   return ACE_Sig_Handler::register_handler_i (signum,
00196                                               new_sh,
00197                                               new_disp,
00198                                               old_sh,
00199                                               old_disp);
00200 }
00201 
00202 // Remove an ACE_Event_Handler.
00203 
00204 int
00205 ACE_Sig_Handler::remove_handler (int signum,
00206                                  ACE_Sig_Action *new_disp,
00207                                  ACE_Sig_Action *old_disp,
00208                                  int)
00209 {
00210   ACE_TRACE ("ACE_Sig_Handler::remove_handler");
00211   ACE_MT (ACE_Recursive_Thread_Mutex *lock =
00212     ACE_Managed_Object<ACE_Recursive_Thread_Mutex>::get_preallocated_object
00213       (ACE_Object_Manager::ACE_SIG_HANDLER_LOCK);
00214     ACE_Guard<ACE_Recursive_Thread_Mutex> m (*lock));
00215 
00216   if (ACE_Sig_Handler::in_range (signum))
00217     {
00218       ACE_Sig_Action sa (SIG_DFL, (sigset_t *) 0); // Define the default disposition.
00219 
00220       if (new_disp == 0)
00221         new_disp = &sa;
00222 
00223       ACE_Sig_Handler::signal_handlers_[signum] = 0;
00224 
00225       // Register either the new disposition or restore the default.
00226       return new_disp->register_action (signum, old_disp);
00227     }
00228 
00229     return -1;
00230 }
00231 
00232 // Master dispatcher function that gets called by a signal handler and
00233 // dispatches one handler...
00234 
00235 void
00236 ACE_Sig_Handler::dispatch (int signum,
00237                            siginfo_t *siginfo,
00238                            ucontext_t *ucontext)
00239 {
00240   ACE_TRACE ("ACE_Sig_Handler::dispatch");
00241 
00242   // Save/restore errno.
00243   ACE_Errno_Guard error (errno);
00244 
00245   // We can't use the <sig_pending> call here because that acquires
00246   // the lock, which is non-portable...
00247   ACE_Sig_Handler::sig_pending_ = 1;
00248 
00249   // Darn well better be in range since the OS dispatched this...
00250   ACE_ASSERT (ACE_Sig_Handler::in_range (signum));
00251 
00252   ACE_Event_Handler *eh = ACE_Sig_Handler::signal_handlers_[signum];
00253 
00254   if (eh != 0)
00255     {
00256       if (eh->handle_signal (signum, siginfo, ucontext) == -1)
00257         {
00258           // Define the default disposition.
00259           ACE_Sig_Action sa ((ACE_SignalHandler) SIG_DFL, (sigset_t *) 0);
00260 
00261           ACE_Sig_Handler::signal_handlers_[signum] = 0;
00262 
00263           // Remove the current disposition by registering the default
00264           // disposition.
00265           sa.register_action (signum);
00266 
00267           // Allow the event handler to close down if necessary.
00268           eh->handle_close (ACE_INVALID_HANDLE,
00269                             ACE_Event_Handler::SIGNAL_MASK);
00270         }
00271 #if defined (ACE_WIN32)
00272       else
00273         // Win32 is weird in the sense that it resets the signal
00274         // disposition to SIG_DFL after a signal handler is
00275         // dispatched.  Therefore, to workaround this "feature" we
00276         // must re-register the <ACE_Event_Handler> with <signum>
00277         // explicitly.
00278         ACE_Sig_Handler::register_handler_i (signum,
00279                                              eh);
00280 #endif /* ACE_WIN32*/
00281     }
00282 }
00283 
00284 // ----------------------------------------
00285 // The following classes are local to this file.
00286 
00287 // There are bugs with HP/UX's C++ compiler that prevents this stuff
00288 // from compiling...
00289 #if !defined (ACE_HAS_BROKEN_HPUX_TEMPLATES)
00290 #define ACE_MAX_SIGNAL_HANDLERS ((size_t) 20)
00291 
00292 // Keeps track of the id that uniquely identifies each registered
00293 // signal handler.  This id can be used to cancel a timer via the
00294 // <remove_handler> method.
00295 int ACE_Sig_Handlers::sigkey_ = 0;
00296 
00297 // If this is > 0 then a 3rd party library has registered a
00298 // handler...
00299 int ACE_Sig_Handlers::third_party_sig_handler_ = 0;
00300 
00301 // Make life easier by defining typedefs...
00302 typedef ACE_Fixed_Set <ACE_Event_Handler *, ACE_MAX_SIGNAL_HANDLERS> ACE_SIG_HANDLERS_SET;
00303 typedef ACE_Fixed_Set_Iterator <ACE_Event_Handler *, ACE_MAX_SIGNAL_HANDLERS> ACE_SIG_HANDLERS_ITERATOR;
00304 
00305 class ACE_Sig_Handlers_Set
00306 {
00307 public:
00308   static ACE_SIG_HANDLERS_SET *instance (int signum);
00309 
00310 private:
00311   static ACE_SIG_HANDLERS_SET *sig_handlers_[ACE_NSIG];
00312 };
00313 
00314 /* static */
00315 ACE_SIG_HANDLERS_SET *ACE_Sig_Handlers_Set::sig_handlers_[ACE_NSIG];
00316 
00317 /* static */
00318 ACE_SIG_HANDLERS_SET *
00319 ACE_Sig_Handlers_Set::instance (int signum)
00320 {
00321   if (signum <= 0 || signum >= ACE_NSIG)
00322     return 0; // This will cause problems...
00323   else if (ACE_Sig_Handlers_Set::sig_handlers_[signum] == 0)
00324     ACE_NEW_RETURN (ACE_Sig_Handlers_Set::sig_handlers_[signum],
00325                     ACE_SIG_HANDLERS_SET,
00326                     0);
00327   return ACE_Sig_Handlers_Set::sig_handlers_[signum];
00328 }
00329 
00330 ACE_ALLOC_HOOK_DEFINE(ACE_Sig_Handlers)
00331 
00332 void
00333 ACE_Sig_Handlers::dump (void) const
00334 {
00335 #if defined (ACE_HAS_DUMP)
00336   ACE_TRACE ("ACE_Sig_Handlers::dump");
00337 #endif /* ACE_HAS_DUMP */
00338 }
00339 
00340 // This is the method that does all the dirty work...  The basic
00341 // structure of this method was devised by Detlef Becker.
00342 
00343 int
00344 ACE_Sig_Handlers::register_handler (int signum,
00345                                     ACE_Event_Handler *new_sh,
00346                                     ACE_Sig_Action *new_disp,
00347                                     ACE_Event_Handler **,
00348                                     ACE_Sig_Action *old_disp)
00349 {
00350   ACE_TRACE ("ACE_Sig_Handlers::register_handler");
00351   ACE_MT (ACE_Recursive_Thread_Mutex *lock =
00352     ACE_Managed_Object<ACE_Recursive_Thread_Mutex>::get_preallocated_object
00353       (ACE_Object_Manager::ACE_SIG_HANDLER_LOCK);
00354     ACE_Guard<ACE_Recursive_Thread_Mutex> m (*lock));
00355 
00356   if (ACE_Sig_Handler::in_range (signum))
00357     {
00358       ACE_Sig_Adapter *ace_sig_adapter = 0; // Our signal handler.
00359       ACE_Sig_Adapter *extern_sh = 0; // An external signal handler.
00360       ACE_Sig_Action sa;
00361 
00362       // Get current signal disposition.
00363       sa.retrieve_action (signum);
00364 
00365       // Check whether we are already in control of the signal
00366       // handling disposition...
00367 
00368       if (!(sa.handler () == ace_signal_handlers_dispatcher
00369           || sa.handler () == ACE_SignalHandler (SIG_IGN)
00370           || sa.handler () == ACE_SignalHandler (SIG_DFL)))
00371         {
00372           // Drat, a 3rd party library has already installed a signal ;-(
00373 
00374           // Upto here we never disabled RESTART_MODE.  Thus,
00375           // RESTART_MODE can only be changed by 3rd party libraries.
00376 
00377           if (ACE_BIT_DISABLED (sa.flags (), SA_RESTART)
00378               && ACE_Sig_Handlers::third_party_sig_handler_)
00379             // Toggling is disallowed since we might break 3rd party
00380             // code.
00381             return -1;
00382 
00383           // Note that we've seen a 3rd party handler...
00384           ACE_Sig_Handlers::third_party_sig_handler_ = 1;
00385 
00386           // Create a new 3rd party disposition, remembering its
00387           // preferred signal blocking etc...;
00388           ACE_NEW_RETURN (extern_sh,
00389                           ACE_Sig_Adapter (sa,
00390                                            ++ACE_Sig_Handlers::sigkey_),
00391                           -1);
00392           // Add the external signal handler to the set of handlers
00393           // for this signal.
00394           if (ACE_Sig_Handlers_Set::instance (signum)->insert (extern_sh) == -1)
00395             {
00396               delete extern_sh;
00397               return -1;
00398             }
00399         }
00400       // Add our new handler at this point.
00401       ACE_NEW_RETURN (ace_sig_adapter,
00402                       ACE_Sig_Adapter (new_sh,
00403                                        ++ACE_Sig_Handlers::sigkey_),
00404                       -1);
00405       // Add the ACE signal handler to the set of handlers for this
00406       // signal (make sure it goes before the external one if there is
00407       // one of these).
00408       if (ACE_Sig_Handlers_Set::instance (signum)->insert (ace_sig_adapter) == -1)
00409         {
00410           // We couldn't reinstall our handler, so let's pretend like
00411           // none of this happened...
00412           if (extern_sh)
00413             {
00414               ACE_Sig_Handlers_Set::instance (signum)->remove (extern_sh);
00415               delete extern_sh;
00416             }
00417           delete ace_sig_adapter;
00418           return -1;
00419         }
00420       // If ACE_Sig_Handlers::dispatch() was set we're done.
00421       else if (sa.handler () == ace_signal_handlers_dispatcher)
00422         return ace_sig_adapter->sigkey ();
00423 
00424       // Otherwise, we need to register our handler function so that
00425       // all signals will be dispatched through ACE.
00426       else
00427         {
00428           // Make sure that new_disp points to a valid location if the
00429           // user doesn't care...
00430           if (new_disp == 0)
00431             new_disp = &sa;
00432 
00433           new_disp->handler (ace_signal_handlers_dispatcher);
00434 
00435           // Default is to restart signal handlers.
00436           new_disp->flags (new_disp->flags () | SA_RESTART);
00437           new_disp->flags (new_disp->flags () | SA_SIGINFO);
00438 
00439           // Finally install (possibly reinstall) the ACE signal
00440           // handler disposition with the SA_RESTART mode enabled.
00441           if (new_disp->register_action (signum, old_disp) == -1)
00442             {
00443               // Yikes, lots of roll back at this point...
00444               ACE_Sig_Handlers_Set::instance (signum)->remove (ace_sig_adapter);
00445               delete ace_sig_adapter;
00446 
00447               if (extern_sh)
00448                 {
00449                   ACE_Sig_Handlers_Set::instance (signum)->remove (extern_sh);
00450                   delete extern_sh;
00451                 }
00452               return -1;
00453             }
00454           else // Return the signal key so that programs can cancel this
00455             // handler if they want!
00456             return ace_sig_adapter->sigkey ();
00457         }
00458     }
00459 
00460   return -1;
00461 }
00462 
00463 // Remove the ACE_Event_Handler currently associated with <signum>.
00464 // Install the new disposition (if given) and return the previous
00465 // disposition (if desired by the caller).  Returns 0 on success and
00466 // -1 if <signum> is invalid.
00467 
00468 int
00469 ACE_Sig_Handlers::remove_handler (int signum,
00470                                   ACE_Sig_Action *new_disp,
00471                                   ACE_Sig_Action *old_disp,
00472                                   int sigkey)
00473 {
00474   ACE_TRACE ("ACE_Sig_Handlers::remove_handler");
00475   ACE_MT (ACE_Recursive_Thread_Mutex *lock =
00476     ACE_Managed_Object<ACE_Recursive_Thread_Mutex>::get_preallocated_object
00477       (ACE_Object_Manager::ACE_SIG_HANDLER_LOCK);
00478     ACE_Guard<ACE_Recursive_Thread_Mutex> m (*lock));
00479 
00480   if (ACE_Sig_Handler::in_range (signum))
00481     {
00482       ACE_SIG_HANDLERS_SET *handler_set =
00483         ACE_Sig_Handlers_Set::instance (signum);
00484 
00485       ACE_SIG_HANDLERS_ITERATOR handler_iterator (*handler_set);
00486 
00487       // Iterate through the set of handlers for this signal.
00488 
00489       for (ACE_Event_Handler **eh;
00490            handler_iterator.next (eh) != 0;
00491            handler_iterator.advance ())
00492         {
00493           // Type-safe downcast would be nice here...
00494           ACE_Sig_Adapter *sh = (ACE_Sig_Adapter *) *eh;
00495 
00496           // Remove the handler if (1) its key matches the key we've
00497           // been told to remove or (2) if we've been told to remove
00498           // *all* handlers (i.e., <sigkey> == -1).
00499 
00500           if (sh->sigkey () == sigkey || sigkey == -1)
00501             {
00502               handler_set->remove (*eh);
00503               delete *eh;
00504             }
00505         }
00506 
00507       if (handler_set->size () == 0)
00508         {
00509           // If there are no more handlers left for a signal then
00510           // register the new disposition or restore the default
00511           // disposition.
00512 
00513           ACE_Sig_Action sa (SIG_DFL, (sigset_t *) 0);
00514 
00515           if (new_disp == 0)
00516             new_disp = &sa;
00517 
00518           return new_disp->register_action (signum, old_disp);
00519         }
00520       return 0;
00521     }
00522   else
00523     return -1;
00524 }
00525 
00526 // Master dispatcher function that gets called by a signal handler and
00527 // dispatches *all* the handlers...
00528 
00529 void
00530 ACE_Sig_Handlers::dispatch (int signum,
00531                             siginfo_t *siginfo,
00532                             ucontext_t *ucontext)
00533 {
00534   ACE_TRACE ("ACE_Sig_Handlers::dispatch");
00535   // The following is #ifdef'd out because it's entirely non-portable
00536   // to acquire a mutex in a signal handler...
00537 #if 0
00538   ACE_MT (ACE_Recursive_Thread_Mutex *lock =
00539     ACE_Managed_Object<ACE_Recursive_Thread_Mutex>::get_preallocated_object
00540       (ACE_Object_Manager::ACE_SIG_HANDLER_LOCK);
00541     ACE_TSS_Guard<ACE_Recursive_Thread_Mutex> m (*lock));
00542 #endif /* 0 */
00543 
00544   // Save/restore errno.
00545   ACE_Errno_Guard error (errno);
00546 
00547   ACE_Sig_Handler::sig_pending_ = 1;
00548 
00549   // Darn well better be in range since the OS dispatched this...
00550   ACE_ASSERT (ACE_Sig_Handler::in_range (signum));
00551 
00552   ACE_SIG_HANDLERS_SET *handler_set =
00553     ACE_Sig_Handlers_Set::instance (signum);
00554 
00555   ACE_SIG_HANDLERS_ITERATOR handler_iterator (*handler_set);
00556 
00557   for (ACE_Event_Handler **eh = 0;
00558        handler_iterator.next (eh) != 0;
00559        handler_iterator.advance ())
00560     {
00561       if ((*eh)->handle_signal (signum, siginfo, ucontext) == -1)
00562         {
00563           handler_set->remove (*eh);
00564           delete *eh;
00565         }
00566     }
00567 }
00568 
00569 // Return the first item in the list of handlers.  Note that this will
00570 // trivially provide the same behavior as the ACE_Sig_Handler
00571 // version if there is only 1 handler registered!
00572 
00573 ACE_Event_Handler *
00574 ACE_Sig_Handlers::handler (int signum)
00575 {
00576   ACE_TRACE ("ACE_Sig_Handlers::handler");
00577   ACE_SIG_HANDLERS_SET *handler_set =
00578     ACE_Sig_Handlers_Set::instance (signum);
00579   ACE_SIG_HANDLERS_ITERATOR handler_iterator (*handler_set);
00580   ACE_Event_Handler **eh = 0;
00581   handler_iterator.next (eh);
00582   return *eh;
00583 }
00584 
00585 // The following is a strange bit of logic that tries to give the same
00586 // semantics as what happens in ACE_Sig_Handler when we replace the
00587 // current signal handler with a new one.  Note that if there is only
00588 // one signal handler the behavior will be identical.  If there is
00589 // more than one handler then things get weird...
00590 
00591 ACE_Event_Handler *
00592 ACE_Sig_Handlers::handler (int signum, ACE_Event_Handler *new_sh)
00593 {
00594   ACE_TRACE ("ACE_Sig_Handlers::handler");
00595   ACE_SIG_HANDLERS_SET *handler_set =
00596     ACE_Sig_Handlers_Set::instance (signum);
00597   ACE_SIG_HANDLERS_ITERATOR handler_iterator (*handler_set);
00598   ACE_Event_Handler **eh = 0;
00599 
00600   // Find the first handler...
00601   handler_iterator.next (eh);
00602 
00603   // ... then remove it from the set ...
00604   handler_set->remove (*eh);
00605 
00606   // ... and then insert the new signal handler into the beginning of
00607   // the set (note, this is a bit too tied up in the implementation of
00608   // ACE_Unbounded_Set...).
00609   ACE_Sig_Adapter *temp;
00610 
00611   ACE_NEW_RETURN (temp,
00612                   ACE_Sig_Adapter (new_sh,
00613                                    ++ACE_Sig_Handlers::sigkey_),
00614                   0);
00615   handler_set->insert (temp);
00616   return *eh;
00617 }
00618 
00619 #endif /* ACE_HAS_BROKEN_HPUX_TEMPLATES */
00620 
00621 ACE_END_VERSIONED_NAMESPACE_DECL

Generated on Sun Jan 27 12:05:37 2008 for ACE by doxygen 1.3.6