Public Member Functions | Static Public Member Functions | Public Attributes | Static Private Attributes

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 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;
}


Member Data Documentation

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:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines