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>


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_Handler * | handler (int signum) |
| virtual ACE_Event_Handler * | handler (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 |
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.
| void ACE_Sig_Handlers::dispatch | ( | int | signum, | |
| siginfo_t * | siginfo, | |||
| ucontext_t * | ucontext | |||
| ) | [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 529 of file Sig_Handler.cpp.
{
ACE_TRACE ("ACE_Sig_Handlers::dispatch");
// The following is #ifdef'd out because it's entirely non-portable
// to acquire a mutex in a signal handler...
#if 0
ACE_MT (ACE_Recursive_Thread_Mutex *lock =
ACE_Managed_Object<ACE_Recursive_Thread_Mutex>::get_preallocated_object
(ACE_Object_Manager::ACE_SIG_HANDLER_LOCK);
ACE_TSS_Guard<ACE_Recursive_Thread_Mutex> m (*lock));
#endif /* 0 */
// Save/restore errno.
ACE_Errno_Guard error (errno);
ACE_Sig_Handler::sig_pending_ = 1;
// Darn well better be in range since the OS dispatched this...
ACE_ASSERT (ACE_Sig_Handler::in_range (signum));
ACE_SIG_HANDLERS_SET *handler_set =
ACE_Sig_Handlers_Set::instance (signum);
ACE_SIG_HANDLERS_ITERATOR handler_iterator (*handler_set);
for (ACE_Event_Handler **eh = 0;
handler_iterator.next (eh) != 0;
)
if ((*eh)->handle_signal (signum, siginfo, ucontext) == -1)
{
handler_set->remove (*eh);
delete *eh;
}
}
| void ACE_Sig_Handlers::dump | ( | void | ) | const |
Dump the state of an object.
Reimplemented from ACE_Sig_Handler.
Definition at line 327 of file Sig_Handler.cpp.
{
#if defined (ACE_HAS_DUMP)
ACE_TRACE ("ACE_Sig_Handlers::dump");
#endif /* ACE_HAS_DUMP */
}
| ACE_Event_Handler * ACE_Sig_Handlers::handler | ( | int | signum, | |
| ACE_Event_Handler * | new_sh | |||
| ) | [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 589 of file Sig_Handler.cpp.
{
ACE_TRACE ("ACE_Sig_Handlers::handler");
ACE_SIG_HANDLERS_SET *handler_set =
ACE_Sig_Handlers_Set::instance (signum);
ACE_SIG_HANDLERS_ITERATOR handler_iterator (*handler_set);
ACE_Event_Handler **eh = 0;
// Find the first handler...
handler_iterator.next (eh);
// ... then remove it from the set ...
handler_set->remove (*eh);
// ... and then insert the new signal handler into the beginning of
// the set (note, this is a bit too tied up in the implementation of
// ACE_Unbounded_Set...).
ACE_Sig_Adapter *temp = 0;
ACE_NEW_RETURN (temp,
ACE_Sig_Adapter (new_sh,
++ACE_Sig_Handlers::sigkey_),
0);
handler_set->insert (temp);
return *eh;
}
| 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 571 of file Sig_Handler.cpp.
{
ACE_TRACE ("ACE_Sig_Handlers::handler");
ACE_SIG_HANDLERS_SET *handler_set =
ACE_Sig_Handlers_Set::instance (signum);
ACE_SIG_HANDLERS_ITERATOR handler_iterator (*handler_set);
ACE_Event_Handler **eh = 0;
handler_iterator.next (eh);
return *eh;
}
| 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 338 of file Sig_Handler.cpp.
{
ACE_TRACE ("ACE_Sig_Handlers::register_handler");
ACE_MT (ACE_Recursive_Thread_Mutex *lock =
ACE_Managed_Object<ACE_Recursive_Thread_Mutex>::get_preallocated_object
(ACE_Object_Manager::ACE_SIG_HANDLER_LOCK);
ACE_Guard<ACE_Recursive_Thread_Mutex> m (*lock));
if (ACE_Sig_Handler::in_range (signum))
{
ACE_Sig_Adapter *ace_sig_adapter = 0; // Our signal handler.
ACE_Sig_Adapter *extern_sh = 0; // An external signal handler.
ACE_Sig_Action sa;
// Get current signal disposition.
sa.retrieve_action (signum);
// Check whether we are already in control of the signal
// handling disposition...
if (!(sa.handler () == ace_signal_handlers_dispatcher
|| sa.handler () == ACE_SignalHandler (SIG_IGN)
|| sa.handler () == ACE_SignalHandler (SIG_DFL)))
{
// Drat, a 3rd party library has already installed a signal ;-(
// Upto here we never disabled RESTART_MODE. Thus,
// RESTART_MODE can only be changed by 3rd party libraries.
if (ACE_BIT_DISABLED (sa.flags (), SA_RESTART)
&& ACE_Sig_Handlers::third_party_sig_handler_)
// Toggling is disallowed since we might break 3rd party
// code.
return -1;
// Note that we've seen a 3rd party handler...
ACE_Sig_Handlers::third_party_sig_handler_ = true;
// Create a new 3rd party disposition, remembering its
// preferred signal blocking etc...;
ACE_NEW_RETURN (extern_sh,
ACE_Sig_Adapter (sa,
++ACE_Sig_Handlers::sigkey_),
-1);
// Add the external signal handler to the set of handlers
// for this signal.
if (ACE_Sig_Handlers_Set::instance (signum)->insert (extern_sh) == -1)
{
delete extern_sh;
return -1;
}
}
// Add our new handler at this point.
ACE_NEW_RETURN (ace_sig_adapter,
ACE_Sig_Adapter (new_sh,
++ACE_Sig_Handlers::sigkey_),
-1);
// Add the ACE signal handler to the set of handlers for this
// signal (make sure it goes before the external one if there is
// one of these).
int result = ACE_Sig_Handlers_Set::instance (signum)->insert (ace_sig_adapter);
if (result == -1)
{
// We couldn't reinstall our handler, so let's pretend like
// none of this happened...
if (extern_sh)
{
ACE_Sig_Handlers_Set::instance (signum)->remove (extern_sh);
delete extern_sh;
}
delete ace_sig_adapter;
return -1;
}
// If ACE_Sig_Handlers::dispatch() was set we're done.
else if (sa.handler () == ace_signal_handlers_dispatcher)
return ace_sig_adapter->sigkey ();
// Otherwise, we need to register our handler function so that
// all signals will be dispatched through ACE.
else
{
// Make sure that new_disp points to a valid location if the
// user doesn't care...
if (new_disp == 0)
new_disp = &sa;
new_disp->handler (ace_signal_handlers_dispatcher);
// Default is to restart signal handlers.
new_disp->flags (new_disp->flags () | SA_RESTART);
#if !defined (ACE_HAS_LYNXOS4_SIGNALS)
new_disp->flags (new_disp->flags () | SA_SIGINFO);
#endif /* ACE_HAS_LYNXOS4_SIGNALS */
// Finally install (possibly reinstall) the ACE signal
// handler disposition with the SA_RESTART mode enabled.
if (new_disp->register_action (signum, old_disp) == -1)
{
// Yikes, lots of roll back at this point...
ACE_Sig_Handlers_Set::instance (signum)->remove (ace_sig_adapter);
delete ace_sig_adapter;
if (extern_sh)
{
ACE_Sig_Handlers_Set::instance (signum)->remove (extern_sh);
delete extern_sh;
}
return -1;
}
else // Return the signal key so that programs can cancel this
// handler if they want!
return ace_sig_adapter->sigkey ();
}
}
return -1;
}
| 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 468 of file Sig_Handler.cpp.
{
ACE_TRACE ("ACE_Sig_Handlers::remove_handler");
ACE_MT (ACE_Recursive_Thread_Mutex *lock =
ACE_Managed_Object<ACE_Recursive_Thread_Mutex>::get_preallocated_object
(ACE_Object_Manager::ACE_SIG_HANDLER_LOCK);
ACE_Guard<ACE_Recursive_Thread_Mutex> m (*lock));
if (ACE_Sig_Handler::in_range (signum))
{
ACE_SIG_HANDLERS_SET *handler_set =
ACE_Sig_Handlers_Set::instance (signum);
ACE_SIG_HANDLERS_ITERATOR handler_iterator (*handler_set);
// Iterate through the set of handlers for this signal.
for (ACE_Event_Handler **eh;
handler_iterator.next (eh) != 0;
)
{
// Type-safe downcast would be nice here...
ACE_Sig_Adapter *sh = (ACE_Sig_Adapter *) *eh;
// Remove the handler if (1) its key matches the key we've
// been told to remove or (2) if we've been told to remove
// *all* handlers (i.e., <sigkey> == -1).
if (sh->sigkey () == sigkey || sigkey == -1)
{
handler_set->remove (*eh);
delete *eh;
}
}
if (handler_set->size () == 0)
{
// If there are no more handlers left for a signal then
// register the new disposition or restore the default
// disposition.
ACE_Sig_Action sa (SIG_DFL, (sigset_t *) 0);
if (new_disp == 0)
new_disp = &sa;
return new_disp->register_action (signum, old_disp);
}
return 0;
}
else
return -1;
}
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.
1.7.0