ACE_Sig_Handler Class Reference

This is the main dispatcher of signals for ACE. It improves the existing UNIX signal handling mechanism by allowing C++ objects to handle signals in a way that avoids the use of global/static variables and functions. More...

#include <Sig_Handler.h>

Inheritance diagram for ACE_Sig_Handler:

Inheritance graph
[legend]
Collaboration diagram for ACE_Sig_Handler:

Collaboration graph
[legend]
List of all members.

Public Member Functions

 ACE_Sig_Handler (void)
 Default constructor.
virtual ~ACE_Sig_Handler (void)
 Destructor.
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 ACE_Sig_Handler associated with 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 int sig_pending (void)
 True if there is a pending signal.
static void sig_pending (int)
 Reset the value of <sig_pending_> so that no signal is pending.
static void dispatch (int, siginfo_t *, ucontext_t *)

Public Attributes

 ACE_ALLOC_HOOK_DECLARE
 Declare the dynamic allocation hooks.

Static Protected Member Functions

static ACE_Event_Handlerhandler_i (int signum, ACE_Event_Handler *)
static int register_handler_i (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)
static int in_range (int signum)
 Check whether the SIGNUM is within the legal range of signals.

Static Protected Attributes

static sig_atomic_t sig_pending_ = 0
 Keeps track of whether a signal is pending.

Static Private Attributes

static ACE_Event_Handlersignal_handlers_ [ACE_NSIG]

Detailed Description

This is the main dispatcher of signals for ACE. It improves the existing UNIX signal handling mechanism by allowing C++ objects to handle signals in a way that avoids the use of global/static variables and functions.

Using this class a program can register an 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 method of the registered ACE_Event_Handler is invoked automatically.

Definition at line 43 of file Sig_Handler.h.


Constructor & Destructor Documentation

ACE_INLINE ACE_Sig_Handler::ACE_Sig_Handler ( void   ) 

Default constructor.

Definition at line 6 of file Sig_Handler.inl.

00007 {
00008 }

ACE_Sig_Handler::~ACE_Sig_Handler ( void   )  [virtual]

Destructor.

Definition at line 55 of file Sig_Handler.cpp.

00056 {
00057 }


Member Function Documentation

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

Callback routine registered with sigaction(2) that dispatches the <handle_signal> method of the appropriate pre-registered ACE_Event_Handler.

Reimplemented in ACE_Sig_Handlers.

Definition at line 232 of file Sig_Handler.cpp.

References ACE_ASSERT, ACE_TRACE, ACE_Event_Handler::handle_close(), ACE_Event_Handler::handle_signal(), in_range(), register_handler_i(), SIG_DFL, and ACE_Event_Handler::SIGNAL_MASK.

00235 {
00236   ACE_TRACE ("ACE_Sig_Handler::dispatch");
00237 
00238   // Save/restore errno.
00239   ACE_Errno_Guard error (errno);
00240 
00241   // We can't use the <sig_pending> call here because that acquires
00242   // the lock, which is non-portable...
00243   ACE_Sig_Handler::sig_pending_ = 1;
00244 
00245   // Darn well better be in range since the OS dispatched this...
00246   ACE_ASSERT (ACE_Sig_Handler::in_range (signum));
00247 
00248   ACE_Event_Handler *eh = ACE_Sig_Handler::signal_handlers_[signum];
00249 
00250   if (eh != 0)
00251     {
00252       if (eh->handle_signal (signum, siginfo, ucontext) == -1)
00253         {
00254           // Define the default disposition.
00255           ACE_Sig_Action sa ((ACE_SignalHandler) SIG_DFL, (sigset_t *) 0);
00256 
00257           ACE_Sig_Handler::signal_handlers_[signum] = 0;
00258 
00259           // Remove the current disposition by registering the default
00260           // disposition.
00261           sa.register_action (signum);
00262 
00263           // Allow the event handler to close down if necessary.
00264           eh->handle_close (ACE_INVALID_HANDLE,
00265                             ACE_Event_Handler::SIGNAL_MASK);
00266         }
00267 #if defined (ACE_WIN32)
00268       else
00269         // Win32 is weird in the sense that it resets the signal
00270         // disposition to SIG_DFL after a signal handler is
00271         // dispatched.  Therefore, to workaround this "feature" we
00272         // must re-register the <ACE_Event_Handler> with <signum>
00273         // explicitly.
00274         ACE_Sig_Handler::register_handler_i (signum,
00275                                              eh);
00276 #endif /* ACE_WIN32*/
00277     }
00278 }

void ACE_Sig_Handler::dump ( void   )  const

Dump the state of an object.

Reimplemented in ACE_Sig_Handlers.

Definition at line 60 of file Sig_Handler.cpp.

References ACE_TRACE.

Referenced by ACE_Select_Reactor_T< ACE_SELECT_REACTOR_TOKEN >::dump().

00061 {
00062 #if defined (ACE_HAS_DUMP)
00063   ACE_TRACE ("ACE_Sig_Handler::dump");
00064 #endif /* ACE_HAS_DUMP */
00065 }

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

Set a new ACE_Event_Handler that is associated with signum. Return the existing handler.

Reimplemented in ACE_Sig_Handlers.

Definition at line 123 of file Sig_Handler.cpp.

References ACE_TRACE, and handler_i().

00125 {
00126   ACE_TRACE ("ACE_Sig_Handler::handler");
00127   ACE_MT (ACE_Recursive_Thread_Mutex *lock =
00128     ACE_Managed_Object<ACE_Recursive_Thread_Mutex>::get_preallocated_object
00129       (ACE_Object_Manager::ACE_SIG_HANDLER_LOCK);
00130     ACE_Guard<ACE_Recursive_Thread_Mutex> m (*lock));
00131 
00132   return ACE_Sig_Handler::handler_i (signum, new_sh);
00133 }

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

Return the ACE_Sig_Handler associated with signum.

Reimplemented in ACE_Sig_Handlers.

Definition at line 91 of file Sig_Handler.cpp.

References ACE_TRACE, and in_range().

Referenced by ACE_Select_Reactor_T< ACE_SELECT_REACTOR_TOKEN >::handler_i().

00092 {
00093   ACE_TRACE ("ACE_Sig_Handler::handler");
00094   ACE_MT (ACE_Recursive_Thread_Mutex *lock =
00095     ACE_Managed_Object<ACE_Recursive_Thread_Mutex>::get_preallocated_object
00096       (ACE_Object_Manager::ACE_SIG_HANDLER_LOCK);
00097     ACE_Guard<ACE_Recursive_Thread_Mutex> m (*lock));
00098 
00099   if (ACE_Sig_Handler::in_range (signum))
00100     return ACE_Sig_Handler::signal_handlers_[signum];
00101   else
00102     return 0;
00103 }

ACE_Event_Handler * ACE_Sig_Handler::handler_i ( int  signum,
ACE_Event_Handler  
) [static, protected]

Set a new ACE_Event_Handler that is associated with signum. Return the existing handler. Does not acquire any locks so that it can be called from a signal handler, such as <dispatch>.

Definition at line 106 of file Sig_Handler.cpp.

References ACE_TRACE, and in_range().

Referenced by handler(), and register_handler_i().

00108 {
00109   ACE_TRACE ("ACE_Sig_Handler::handler_i");
00110 
00111   if (ACE_Sig_Handler::in_range (signum))
00112     {
00113       ACE_Event_Handler *sh = ACE_Sig_Handler::signal_handlers_[signum];
00114 
00115       ACE_Sig_Handler::signal_handlers_[signum] = new_sh;
00116       return sh;
00117     }
00118   else
00119     return 0;
00120 }

ACE_INLINE int ACE_Sig_Handler::in_range ( int  signum  )  [static, protected]

Check whether the SIGNUM is within the legal range of signals.

Definition at line 11 of file Sig_Handler.inl.

References ACE_NSIG, and ACE_TRACE.

Referenced by ACE_Sig_Handlers::dispatch(), dispatch(), handler(), handler_i(), ACE_Sig_Handlers::register_handler(), register_handler_i(), ACE_Sig_Handlers::remove_handler(), and remove_handler().

00012 {
00013   ACE_TRACE ("ACE_Sig_Handler::in_range");
00014   return signum > 0 && signum < ACE_NSIG;
00015 }

int ACE_Sig_Handler::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 >= 0 on success.

Reimplemented in ACE_Sig_Handlers.

Definition at line 179 of file Sig_Handler.cpp.

References ACE_TRACE, and register_handler_i().

Referenced by ACE_Select_Reactor_T< ACE_SELECT_REACTOR_TOKEN >::register_handler().

00184 {
00185   ACE_TRACE ("ACE_Sig_Handler::register_handler");
00186   ACE_MT (ACE_Recursive_Thread_Mutex *lock =
00187     ACE_Managed_Object<ACE_Recursive_Thread_Mutex>::get_preallocated_object
00188       (ACE_Object_Manager::ACE_SIG_HANDLER_LOCK);
00189     ACE_Guard<ACE_Recursive_Thread_Mutex> m (*lock));
00190 
00191   return ACE_Sig_Handler::register_handler_i (signum,
00192                                               new_sh,
00193                                               new_disp,
00194                                               old_sh,
00195                                               old_disp);
00196 }

int ACE_Sig_Handler::register_handler_i ( 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 
) [static, protected]

This implementation method is called by <register_handler> and dispatch. It doesn't do any locking so that it can be called within a signal handler, such as dispatch. It adds 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 >= 0 on success.

Definition at line 140 of file Sig_Handler.cpp.

References ace_signal_handler_dispatcher, ACE_TRACE, ACE_Sig_Action::flags(), ACE_Sig_Action::handler(), handler_i(), in_range(), ACE_Sig_Action::register_action(), and SA_SIGINFO.

Referenced by dispatch(), and register_handler().

00145 {
00146   ACE_TRACE ("ACE_Sig_Handler::register_handler_i");
00147 
00148   if (ACE_Sig_Handler::in_range (signum))
00149     {
00150       ACE_Sig_Action sa; // Define a "null" action.
00151       ACE_Event_Handler *sh = ACE_Sig_Handler::handler_i (signum,
00152                                                           new_sh);
00153 
00154       // Return a pointer to the old <ACE_Sig_Handler> if the user
00155       // asks for this.
00156       if (old_sh != 0)
00157         *old_sh = sh;
00158 
00159       // Make sure that <new_disp> points to a valid location if the
00160       // user doesn't care...
00161       if (new_disp == 0)
00162         new_disp = &sa;
00163 
00164       new_disp->handler (ace_signal_handler_dispatcher);
00165 #if !defined (ACE_HAS_LYNXOS_SIGNALS)
00166       new_disp->flags (new_disp->flags () | SA_SIGINFO);
00167 #endif /* ACE_HAS_LYNXOS_SIGNALS */
00168       return new_disp->register_action (signum, old_disp);
00169     }
00170   else
00171     return -1;
00172 }

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

Remove the ACE_Event_Handler currently associated with signum. sigkey is ignored in this implementation since there is only one instance of a signal handler. Install the new disposition (if given) and return the previous disposition (if desired by the caller). Returns 0 on success and -1 if signum is invalid.

Reimplemented in ACE_Sig_Handlers.

Definition at line 201 of file Sig_Handler.cpp.

References ACE_TRACE, in_range(), ACE_Sig_Action::register_action(), and SIG_DFL.

Referenced by ACE_Select_Reactor_T< ACE_SELECT_REACTOR_TOKEN >::remove_handler().

00205 {
00206   ACE_TRACE ("ACE_Sig_Handler::remove_handler");
00207   ACE_MT (ACE_Recursive_Thread_Mutex *lock =
00208     ACE_Managed_Object<ACE_Recursive_Thread_Mutex>::get_preallocated_object
00209       (ACE_Object_Manager::ACE_SIG_HANDLER_LOCK);
00210     ACE_Guard<ACE_Recursive_Thread_Mutex> m (*lock));
00211 
00212   if (ACE_Sig_Handler::in_range (signum))
00213     {
00214       ACE_Sig_Action sa (SIG_DFL, (sigset_t *) 0); // Define the default disposition.
00215 
00216       if (new_disp == 0)
00217         new_disp = &sa;
00218 
00219       ACE_Sig_Handler::signal_handlers_[signum] = 0;
00220 
00221       // Register either the new disposition or restore the default.
00222       return new_disp->register_action (signum, old_disp);
00223     }
00224 
00225     return -1;
00226 }

void ACE_Sig_Handler::sig_pending ( int   )  [static]

Reset the value of <sig_pending_> so that no signal is pending.

Definition at line 79 of file Sig_Handler.cpp.

References ACE_TRACE.

00080 {
00081   ACE_TRACE ("ACE_Sig_Handler::sig_pending");
00082 
00083   ACE_MT (ACE_Recursive_Thread_Mutex *lock =
00084           ACE_Managed_Object<ACE_Recursive_Thread_Mutex>::get_preallocated_object
00085           (ACE_Object_Manager::ACE_SIG_HANDLER_LOCK);
00086           ACE_Guard<ACE_Recursive_Thread_Mutex> m (*lock));
00087   ACE_Sig_Handler::sig_pending_ = pending;
00088 }

int ACE_Sig_Handler::sig_pending ( void   )  [static]

True if there is a pending signal.

Definition at line 68 of file Sig_Handler.cpp.

References ACE_TRACE.

Referenced by ACE_Select_Reactor_T< ACE_SELECT_REACTOR_TOKEN >::dispatch().

00069 {
00070   ACE_TRACE ("ACE_Sig_Handler::sig_pending");
00071   ACE_MT (ACE_Recursive_Thread_Mutex *lock =
00072           ACE_Managed_Object<ACE_Recursive_Thread_Mutex>::get_preallocated_object
00073           (ACE_Object_Manager::ACE_SIG_HANDLER_LOCK);
00074           ACE_Guard<ACE_Recursive_Thread_Mutex> m (*lock));
00075   return ACE_Sig_Handler::sig_pending_ != 0;
00076 }


Member Data Documentation

ACE_Sig_Handler::ACE_ALLOC_HOOK_DECLARE

Declare the dynamic allocation hooks.

Reimplemented in ACE_Sig_Handlers.

Definition at line 106 of file Sig_Handler.h.

sig_atomic_t ACE_Sig_Handler::sig_pending_ = 0 [static, protected]

Keeps track of whether a signal is pending.

Definition at line 138 of file Sig_Handler.h.

ACE_BEGIN_VERSIONED_NAMESPACE_DECL ACE_Event_Handler * ACE_Sig_Handler::signal_handlers_ [static, private]

Array used to store one user-defined Event_Handler for every signal.

Definition at line 143 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