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

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

Public Attributes

 ACE_ALLOC_HOOK_DECLARE
 Declare the dynamic allocation hooks.


Static Private Attributes

int sigkey_ = 0
int third_party_sig_handler_ = 0

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 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 method of all the pre-registered ACE_Event_Handlers for signum

Reimplemented from ACE_Sig_Handler.

Definition at line 530 of file Sig_Handler.cpp.

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

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 }

void ACE_Sig_Handlers::dump void   )  const
 

Dump the state of an object.

Reimplemented from ACE_Sig_Handler.

Definition at line 333 of file Sig_Handler.cpp.

References ACE_TRACE.

00334 {
00335 #if defined (ACE_HAS_DUMP)
00336   ACE_TRACE ("ACE_Sig_Handlers::dump");
00337 #endif /* ACE_HAS_DUMP */
00338 }

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 592 of file Sig_Handler.cpp.

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

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 }

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

Return the head of the list of s associated with SIGNUM.

Reimplemented from ACE_Sig_Handler.

Definition at line 574 of file Sig_Handler.cpp.

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

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 }

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 that is >= 0 on success.

Reimplemented from ACE_Sig_Handler.

Definition at line 344 of file Sig_Handler.cpp.

References ACE_BIT_DISABLED, ACE_NEW_RETURN, ace_signal_handlers_dispatcher, ACE_SignalHandler, ACE_TRACE, ACE_Sig_Action::flags(), ACE_Sig_Action::handler(), ACE_Sig_Handler::in_range(), ACE_Fixed_Set< T, ACE_SIZE >::insert(), 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, ACE_Sig_Adapter::sigkey(), sigkey_, and third_party_sig_handler_.

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 }

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 matches the passed as a parameter or (2) if we've been told to remove all the handlers, i.e., == -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 469 of file Sig_Handler.cpp.

References ACE_SIG_HANDLERS_ITERATOR, ACE_SIG_HANDLERS_SET, 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, ACE_Sig_Adapter::sigkey(), and ACE_Fixed_Set< T, ACE_SIZE >::size().

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 }


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 method.

Definition at line 295 of file Sig_Handler.cpp.

Referenced by handler(), and register_handler().

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

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

Definition at line 299 of file Sig_Handler.cpp.

Referenced by register_handler().


The documentation for this class was generated from the following files:
Generated on Sun Jan 27 12:57:35 2008 for ACE by doxygen 1.3.6