ACE_Sig_Handlers Class Reference

This is an alternative signal handling dispatcher for ACE. It allows a list of signal handlers to be registered for each signal. It also makes SA_RESTART the default mode. More...

#include <Sig_Handler.h>

Inheritance diagram for ACE_Sig_Handlers:

Inheritance graph
[legend]
Collaboration diagram for ACE_Sig_Handlers:

Collaboration graph
[legend]
List of all members.

Public Member Functions

virtual int register_handler (int signum, ACE_Event_Handler *new_sh, ACE_Sig_Action *new_disp=0, ACE_Event_Handler **old_sh=0, ACE_Sig_Action *old_disp=0)
virtual int remove_handler (int signum, ACE_Sig_Action *new_disp=0, ACE_Sig_Action *old_disp=0, int sigkey=-1)
virtual ACE_Event_Handlerhandler (int signum)
virtual ACE_Event_Handlerhandler (int signum, ACE_Event_Handler *)
void dump (void) const
 Dump the state of an object.

Static Public Member Functions

static void dispatch (int signum, siginfo_t *, ucontext_t *)

Public Attributes

 ACE_ALLOC_HOOK_DECLARE
 Declare the dynamic allocation hooks.

Static Private Attributes

static int sigkey_ = 0
static bool third_party_sig_handler_ = false

Detailed Description

This is an alternative signal handling dispatcher for ACE. It allows a list of signal handlers to be registered for each signal. It also makes SA_RESTART the default mode.

Using this class a program can register one or more ACE_Event_Handler with the ACE_Sig_Handler in order to handle a designated signum. When a signal occurs that corresponds to this signum, the <handle_signal> methods of all the registered ACE_Event_Handlers are invoked automatically.

Definition at line 160 of file Sig_Handler.h.


Member Function Documentation

void ACE_Sig_Handlers::dispatch ( int  signum,
siginfo_t ,
ucontext_t  
) [static]

Callback routine registered with sigaction(2) that dispatches the <handle_signal> method of all the pre-registered ACE_Event_Handlers for signum

Reimplemented from ACE_Sig_Handler.

Definition at line 525 of file Sig_Handler.cpp.

References ACE_ASSERT, ACE_TRACE, ACE_Fixed_Set_Iterator_Base< T, ACE_SIZE >::advance(), ACE_Sig_Handler::in_range(), ACE_Sig_Handlers_Set::instance(), ACE_Fixed_Set_Iterator< T, ACE_SIZE >::next(), and ACE_Fixed_Set< T, ACE_SIZE >::remove().

00528 {
00529   ACE_TRACE ("ACE_Sig_Handlers::dispatch");
00530   // The following is #ifdef'd out because it's entirely non-portable
00531   // to acquire a mutex in a signal handler...
00532 #if 0
00533   ACE_MT (ACE_Recursive_Thread_Mutex *lock =
00534     ACE_Managed_Object<ACE_Recursive_Thread_Mutex>::get_preallocated_object
00535       (ACE_Object_Manager::ACE_SIG_HANDLER_LOCK);
00536     ACE_TSS_Guard<ACE_Recursive_Thread_Mutex> m (*lock));
00537 #endif /* 0 */
00538 
00539   // Save/restore errno.
00540   ACE_Errno_Guard error (errno);
00541 
00542   ACE_Sig_Handler::sig_pending_ = 1;
00543 
00544   // Darn well better be in range since the OS dispatched this...
00545   ACE_ASSERT (ACE_Sig_Handler::in_range (signum));
00546 
00547   ACE_SIG_HANDLERS_SET *handler_set =
00548     ACE_Sig_Handlers_Set::instance (signum);
00549 
00550   ACE_SIG_HANDLERS_ITERATOR handler_iterator (*handler_set);
00551 
00552   for (ACE_Event_Handler **eh = 0;
00553        handler_iterator.next (eh) != 0;
00554        handler_iterator.advance ())
00555     {
00556       if ((*eh)->handle_signal (signum, siginfo, ucontext) == -1)
00557         {
00558           handler_set->remove (*eh);
00559           delete *eh;
00560         }
00561     }
00562 }

void ACE_Sig_Handlers::dump ( void   )  const

Dump the state of an object.

Reimplemented from ACE_Sig_Handler.

Definition at line 328 of file Sig_Handler.cpp.

References ACE_TRACE.

00329 {
00330 #if defined (ACE_HAS_DUMP)
00331   ACE_TRACE ("ACE_Sig_Handlers::dump");
00332 #endif /* ACE_HAS_DUMP */
00333 }

ACE_Event_Handler * ACE_Sig_Handlers::handler ( int  signum,
ACE_Event_Handler  
) [virtual]

Set a new ACE_Event_Handler that is associated with SIGNUM at the head of the list of signals. Return the existing handler that was at the head.

Reimplemented from ACE_Sig_Handler.

Definition at line 587 of file Sig_Handler.cpp.

References ACE_NEW_RETURN, ACE_TRACE, ACE_Fixed_Set< T, ACE_SIZE >::insert(), ACE_Sig_Handlers_Set::instance(), ACE_Fixed_Set_Iterator< T, ACE_SIZE >::next(), and ACE_Fixed_Set< T, ACE_SIZE >::remove().

00588 {
00589   ACE_TRACE ("ACE_Sig_Handlers::handler");
00590   ACE_SIG_HANDLERS_SET *handler_set =
00591     ACE_Sig_Handlers_Set::instance (signum);
00592   ACE_SIG_HANDLERS_ITERATOR handler_iterator (*handler_set);
00593   ACE_Event_Handler **eh = 0;
00594 
00595   // Find the first handler...
00596   handler_iterator.next (eh);
00597 
00598   // ... then remove it from the set ...
00599   handler_set->remove (*eh);
00600 
00601   // ... and then insert the new signal handler into the beginning of
00602   // the set (note, this is a bit too tied up in the implementation of
00603   // ACE_Unbounded_Set...).
00604   ACE_Sig_Adapter *temp = 0;
00605 
00606   ACE_NEW_RETURN (temp,
00607                   ACE_Sig_Adapter (new_sh,
00608                                    ++ACE_Sig_Handlers::sigkey_),
00609                   0);
00610   handler_set->insert (temp);
00611   return *eh;
00612 }

ACE_Event_Handler * ACE_Sig_Handlers::handler ( int  signum  )  [virtual]

Return the head of the list of <ACE_Sig_Handler>s associated with SIGNUM.

Reimplemented from ACE_Sig_Handler.

Definition at line 569 of file Sig_Handler.cpp.

References ACE_TRACE, ACE_Sig_Handlers_Set::instance(), and ACE_Fixed_Set_Iterator< T, ACE_SIZE >::next().

00570 {
00571   ACE_TRACE ("ACE_Sig_Handlers::handler");
00572   ACE_SIG_HANDLERS_SET *handler_set =
00573     ACE_Sig_Handlers_Set::instance (signum);
00574   ACE_SIG_HANDLERS_ITERATOR handler_iterator (*handler_set);
00575   ACE_Event_Handler **eh = 0;
00576   handler_iterator.next (eh);
00577   return *eh;
00578 }

int ACE_Sig_Handlers::register_handler ( int  signum,
ACE_Event_Handler new_sh,
ACE_Sig_Action new_disp = 0,
ACE_Event_Handler **  old_sh = 0,
ACE_Sig_Action old_disp = 0 
) [virtual]

Add a new ACE_Event_Handler and a new sigaction associated with signum. Passes back the existing ACE_Event_Handler and its sigaction if pointers are non-zero. Returns -1 on failure and a <sigkey> that is >= 0 on success.

Reimplemented from ACE_Sig_Handler.

Definition at line 339 of file Sig_Handler.cpp.

References ACE_BIT_DISABLED, ACE_NEW_RETURN, ace_signal_handlers_dispatcher, ACE_TRACE, ACE_Sig_Action::flags(), ACE_Sig_Action::handler(), ACE_Sig_Handler::in_range(), ACE_Sig_Handlers_Set::instance(), ACE_Sig_Action::register_action(), ACE_Fixed_Set< T, ACE_SIZE >::remove(), ACE_Sig_Action::retrieve_action(), SA_RESTART, SA_SIGINFO, SIG_DFL, SIG_IGN, and ACE_Sig_Adapter::sigkey().

00344 {
00345   ACE_TRACE ("ACE_Sig_Handlers::register_handler");
00346   ACE_MT (ACE_Recursive_Thread_Mutex *lock =
00347     ACE_Managed_Object<ACE_Recursive_Thread_Mutex>::get_preallocated_object
00348       (ACE_Object_Manager::ACE_SIG_HANDLER_LOCK);
00349     ACE_Guard<ACE_Recursive_Thread_Mutex> m (*lock));
00350 
00351   if (ACE_Sig_Handler::in_range (signum))
00352     {
00353       ACE_Sig_Adapter *ace_sig_adapter = 0; // Our signal handler.
00354       ACE_Sig_Adapter *extern_sh = 0; // An external signal handler.
00355       ACE_Sig_Action sa;
00356 
00357       // Get current signal disposition.
00358       sa.retrieve_action (signum);
00359 
00360       // Check whether we are already in control of the signal
00361       // handling disposition...
00362 
00363       if (!(sa.handler () == ace_signal_handlers_dispatcher
00364           || sa.handler () == ACE_SignalHandler (SIG_IGN)
00365           || sa.handler () == ACE_SignalHandler (SIG_DFL)))
00366         {
00367           // Drat, a 3rd party library has already installed a signal ;-(
00368 
00369           // Upto here we never disabled RESTART_MODE.  Thus,
00370           // RESTART_MODE can only be changed by 3rd party libraries.
00371 
00372           if (ACE_BIT_DISABLED (sa.flags (), SA_RESTART)
00373               && ACE_Sig_Handlers::third_party_sig_handler_)
00374             // Toggling is disallowed since we might break 3rd party
00375             // code.
00376             return -1;
00377 
00378           // Note that we've seen a 3rd party handler...
00379           ACE_Sig_Handlers::third_party_sig_handler_ = true;
00380 
00381           // Create a new 3rd party disposition, remembering its
00382           // preferred signal blocking etc...;
00383           ACE_NEW_RETURN (extern_sh,
00384                           ACE_Sig_Adapter (sa,
00385                                            ++ACE_Sig_Handlers::sigkey_),
00386                           -1);
00387           // Add the external signal handler to the set of handlers
00388           // for this signal.
00389           if (ACE_Sig_Handlers_Set::instance (signum)->insert (extern_sh) == -1)
00390             {
00391               delete extern_sh;
00392               return -1;
00393             }
00394         }
00395       // Add our new handler at this point.
00396       ACE_NEW_RETURN (ace_sig_adapter,
00397                       ACE_Sig_Adapter (new_sh,
00398                                        ++ACE_Sig_Handlers::sigkey_),
00399                       -1);
00400       // Add the ACE signal handler to the set of handlers for this
00401       // signal (make sure it goes before the external one if there is
00402       // one of these).
00403       if (ACE_Sig_Handlers_Set::instance (signum)->insert (ace_sig_adapter) == -1)
00404         {
00405           // We couldn't reinstall our handler, so let's pretend like
00406           // none of this happened...
00407           if (extern_sh)
00408             {
00409               ACE_Sig_Handlers_Set::instance (signum)->remove (extern_sh);
00410               delete extern_sh;
00411             }
00412           delete ace_sig_adapter;
00413           return -1;
00414         }
00415       // If ACE_Sig_Handlers::dispatch() was set we're done.
00416       else if (sa.handler () == ace_signal_handlers_dispatcher)
00417         return ace_sig_adapter->sigkey ();
00418 
00419       // Otherwise, we need to register our handler function so that
00420       // all signals will be dispatched through ACE.
00421       else
00422         {
00423           // Make sure that new_disp points to a valid location if the
00424           // user doesn't care...
00425           if (new_disp == 0)
00426             new_disp = &sa;
00427 
00428           new_disp->handler (ace_signal_handlers_dispatcher);
00429 
00430           // Default is to restart signal handlers.
00431           new_disp->flags (new_disp->flags () | SA_RESTART);
00432           new_disp->flags (new_disp->flags () | SA_SIGINFO);
00433 
00434           // Finally install (possibly reinstall) the ACE signal
00435           // handler disposition with the SA_RESTART mode enabled.
00436           if (new_disp->register_action (signum, old_disp) == -1)
00437             {
00438               // Yikes, lots of roll back at this point...
00439               ACE_Sig_Handlers_Set::instance (signum)->remove (ace_sig_adapter);
00440               delete ace_sig_adapter;
00441 
00442               if (extern_sh)
00443                 {
00444                   ACE_Sig_Handlers_Set::instance (signum)->remove (extern_sh);
00445                   delete extern_sh;
00446                 }
00447               return -1;
00448             }
00449           else // Return the signal key so that programs can cancel this
00450             // handler if they want!
00451             return ace_sig_adapter->sigkey ();
00452         }
00453     }
00454 
00455   return -1;
00456 }

int ACE_Sig_Handlers::remove_handler ( int  signum,
ACE_Sig_Action new_disp = 0,
ACE_Sig_Action old_disp = 0,
int  sigkey = -1 
) [virtual]

Remove an ACE_Event_Handler currently associated with signum. We remove the handler if (1) its sigkey> matches the sigkey passed as a parameter or (2) if we've been told to remove all the handlers, i.e., <sigkey> == -1. If a new disposition is given it is installed and the previous disposition is returned (if desired by the caller). Returns 0 on success and -1 if signum is invalid.

Reimplemented from ACE_Sig_Handler.

Definition at line 464 of file Sig_Handler.cpp.

References ACE_TRACE, ACE_Fixed_Set_Iterator_Base< T, ACE_SIZE >::advance(), ACE_Sig_Handler::in_range(), ACE_Sig_Handlers_Set::instance(), ACE_Fixed_Set_Iterator< T, ACE_SIZE >::next(), ACE_Sig_Action::register_action(), ACE_Fixed_Set< T, ACE_SIZE >::remove(), SIG_DFL, and ACE_Fixed_Set< T, ACE_SIZE >::size().

00468 {
00469   ACE_TRACE ("ACE_Sig_Handlers::remove_handler");
00470   ACE_MT (ACE_Recursive_Thread_Mutex *lock =
00471     ACE_Managed_Object<ACE_Recursive_Thread_Mutex>::get_preallocated_object
00472       (ACE_Object_Manager::ACE_SIG_HANDLER_LOCK);
00473     ACE_Guard<ACE_Recursive_Thread_Mutex> m (*lock));
00474 
00475   if (ACE_Sig_Handler::in_range (signum))
00476     {
00477       ACE_SIG_HANDLERS_SET *handler_set =
00478         ACE_Sig_Handlers_Set::instance (signum);
00479 
00480       ACE_SIG_HANDLERS_ITERATOR handler_iterator (*handler_set);
00481 
00482       // Iterate through the set of handlers for this signal.
00483 
00484       for (ACE_Event_Handler **eh;
00485            handler_iterator.next (eh) != 0;
00486            handler_iterator.advance ())
00487         {
00488           // Type-safe downcast would be nice here...
00489           ACE_Sig_Adapter *sh = (ACE_Sig_Adapter *) *eh;
00490 
00491           // Remove the handler if (1) its key matches the key we've
00492           // been told to remove or (2) if we've been told to remove
00493           // *all* handlers (i.e., <sigkey> == -1).
00494 
00495           if (sh->sigkey () == sigkey || sigkey == -1)
00496             {
00497               handler_set->remove (*eh);
00498               delete *eh;
00499             }
00500         }
00501 
00502       if (handler_set->size () == 0)
00503         {
00504           // If there are no more handlers left for a signal then
00505           // register the new disposition or restore the default
00506           // disposition.
00507 
00508           ACE_Sig_Action sa (SIG_DFL, (sigset_t *) 0);
00509 
00510           if (new_disp == 0)
00511             new_disp = &sa;
00512 
00513           return new_disp->register_action (signum, old_disp);
00514         }
00515       return 0;
00516     }
00517   else
00518     return -1;
00519 }


Member Data Documentation

ACE_Sig_Handlers::ACE_ALLOC_HOOK_DECLARE

Declare the dynamic allocation hooks.

Reimplemented from ACE_Sig_Handler.

Definition at line 215 of file Sig_Handler.h.

int ACE_Sig_Handlers::sigkey_ = 0 [static, private]

Keeps track of the id that uniquely identifies each registered signal handler. This id can be used to cancel a timer via the <remove_handler> method.

Definition at line 223 of file Sig_Handler.h.

bool ACE_Sig_Handlers::third_party_sig_handler_ = false [static, private]

If this is true then a 3rd party library has registered a handler...

Definition at line 227 of file Sig_Handler.h.


The documentation for this class was generated from the following files:
Generated on Tue Feb 2 17:35:36 2010 for ACE by  doxygen 1.4.7