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

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 <Signal.h>

Inheritance diagram for ACE_Sig_Handlers:

Inheritance graph
[legend]
Collaboration diagram for ACE_Sig_Handlers:

Collaboration graph
[legend]
List of all members.

Public Methods

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)
 Return the head of the list of <ACE_Sig_Handler>s associated with SIGNUM. More...

virtual ACE_Event_Handlerhandler (int signum, ACE_Event_Handler *)
void dump (void) const
 Dump the state of an object. More...


Static Public Methods

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

Public Attributes

 ACE_ALLOC_HOOK_DECLARE
 Declare the dynamic allocation hooks. More...


Static Private Attributes

int sigkey_ = 0
int third_party_sig_handler_ = 0
 If this is > 0 then a 3rd party library has registered a handler... More...


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 432 of file Signal.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 757 of file Signal.cpp.

References ACE_ASSERT, ACE_MT, ACE_TRACE, ACE_Fixed_Set_Iterator::advance, ACE_Sig_Handler::in_range, ACE_Sig_Handlers_Set::instance, ACE_Fixed_Set_Iterator::next, ACE_Fixed_Set< ACE_Event_Handler *, ACE_MAX_SIGNAL_HANDLERS >::remove, ACE_Sig_Handler::sig_pending_, and ucontext_t.

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 }

void ACE_Sig_Handlers::dump void    const
 

Dump the state of an object.

Reimplemented from ACE_Sig_Handler.

Definition at line 562 of file Signal.cpp.

References ACE_TRACE.

00563 {
00564   ACE_TRACE ("ACE_Sig_Handlers::dump");
00565 }

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 819 of file Signal.cpp.

References ACE_NEW_RETURN, ACE_TRACE, ACE_Fixed_Set< ACE_Event_Handler *, ACE_MAX_SIGNAL_HANDLERS >::insert, ACE_Sig_Handlers_Set::instance, ACE_Fixed_Set_Iterator::next, ACE_Fixed_Set< ACE_Event_Handler *, ACE_MAX_SIGNAL_HANDLERS >::remove, and sigkey_.

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 }

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 801 of file Signal.cpp.

References ACE_TRACE, ACE_Sig_Handlers_Set::instance, and ACE_Fixed_Set_Iterator::next.

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 }

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 571 of file Signal.cpp.

References ACE_BIT_DISABLED, ACE_MT, 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< ACE_Event_Handler *, ACE_MAX_SIGNAL_HANDLERS >::insert, ACE_Sig_Handlers_Set::instance, ACE_Sig_Action::register_action, ACE_Fixed_Set< ACE_Event_Handler *, ACE_MAX_SIGNAL_HANDLERS >::remove, ACE_Sig_Action::retrieve_action, SA_RESTART, SA_SIGINFO, SIG_DFL, SIG_IGN, ACE_Sig_Adapter::sigkey, sigkey_, and third_party_sig_handler_.

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 }

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 696 of file Signal.cpp.

References ACE_MT, ACE_TRACE, ACE_Fixed_Set_Iterator::advance, ACE_Sig_Handler::in_range, ACE_Sig_Handlers_Set::instance, ACE_Fixed_Set_Iterator::next, ACE_Sig_Action::register_action, ACE_Fixed_Set< ACE_Event_Handler *, ACE_MAX_SIGNAL_HANDLERS >::remove, SIG_DFL, ACE_Sig_Adapter::sigkey, and ACE_Fixed_Set< ACE_Event_Handler *, ACE_MAX_SIGNAL_HANDLERS >::size.

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 }


Member Data Documentation

ACE_Sig_Handlers::ACE_ALLOC_HOOK_DECLARE
 

Declare the dynamic allocation hooks.

Reimplemented from ACE_Sig_Handler.

Definition at line 487 of file Signal.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 524 of file Signal.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 528 of file Signal.cpp.

Referenced by register_handler.


The documentation for this class was generated from the following files:
Generated on Mon Jun 16 12:56:10 2003 for ACE by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002