summaryrefslogtreecommitdiff
path: root/ace/Signal.h
diff options
context:
space:
mode:
Diffstat (limited to 'ace/Signal.h')
-rw-r--r--ace/Signal.h350
1 files changed, 350 insertions, 0 deletions
diff --git a/ace/Signal.h b/ace/Signal.h
new file mode 100644
index 00000000000..9396ac8c807
--- /dev/null
+++ b/ace/Signal.h
@@ -0,0 +1,350 @@
+/* -*- C++ -*- */
+// $Id$
+
+
+// ============================================================================
+//
+// = LIBRARY
+// ace
+//
+// = FILENAME
+// Signal.h
+//
+// = AUTHOR
+// Doug Schmidt
+//
+// ============================================================================
+
+#if !defined (ACE_SIGNAL_HANDLER_H)
+#define ACE_SIGNAL_HANDLER_H
+
+#include "ace/Synch.h"
+#include "ace/Event_Handler.h"
+#include "ace/Set.h"
+
+// This worksaround a horrible bug with HP/UX C++...
+typedef struct sigaction ACE_SIGACTION;
+
+class ACE_Export ACE_Sig_Set
+ // = TITLE
+ // Provide a C++ wrapper for the C sigset_t interface.
+ //
+ // = DESCRIPTION
+ // Handle signals via a more elegant C++ interface (e.g.,
+ // doesn't require the use of global variables or global
+ // functions in an application).
+{
+public:
+ // = Initialization and termination methods.
+ ACE_Sig_Set (sigset_t *);
+ ACE_Sig_Set (int fill = 0);
+ ~ACE_Sig_Set (void);
+
+ int empty_set (void);
+ // Create a set that excludes all signals defined by the system.
+
+ int fill_set (void);
+ // Create a set that includes all signals defined by the system.
+
+ int sig_add (int signo);
+ // Adds the individual signal specified by <signo> to the set.
+
+ int sig_del (int signo);
+ // Deletes the individual signal specified by <signo> from the set.
+
+ int is_member (int signo) const;
+ // Checks whether the signal specified by <signo> is in the set.
+
+ operator sigset_t *();
+ // Returns a pointer to the underlying sigset_t.
+
+ void dump (void) const;
+ // Dump the state of an object.
+
+ ACE_ALLOC_HOOK_DECLARE;
+ // Declare the dynamic allocation hooks.
+
+private:
+ sigset_t sigset_;
+ // Set of signals.
+};
+
+class ACE_Export ACE_Sig_Action
+ // = TITLE
+ // C++ wrapper around struct sigaction.
+{
+public:
+ // = Initialization methods.
+ ACE_Sig_Action (void);
+ ACE_Sig_Action (ACE_SignalHandler handler,
+ sigset_t *sigmask = 0,
+ int flags = 0);
+ ACE_Sig_Action (ACE_SignalHandler handler,
+ int signum,
+ sigset_t *sigmask = 0,
+ int flags = 0);
+ ACE_Sig_Action (const ACE_Sig_Action &s);
+ ACE_Sig_Action (struct sigaction *);
+
+ // = Signal action management.
+ int register_action (int signum, ACE_Sig_Action *oaction = 0);
+ // Register <this> as the current disposition and store old
+ // disposition into <oaction> if it is non-NULL.
+
+ int restore_action (int signum, ACE_Sig_Action &oaction);
+ // Assign the value of <oaction> to <this> and make it become the
+ // new signal disposition.
+
+ int retrieve_action (int signum);
+ // Retrieve the current disposition into <this>.
+
+ // = Set/get current signal action.
+ void set (struct sigaction *);
+ struct sigaction *get (void);
+ operator ACE_SIGACTION *();
+
+ // = Set/get current signal flags.
+ void flags (int);
+ int flags (void);
+
+ // = Set/get current signal mask.
+ void mask (sigset_t *);
+ sigset_t *mask (void);
+
+ // = Set/get current signal handler (pointer to function).
+ void handler (ACE_SignalHandler);
+ ACE_SignalHandler handler (void);
+
+ void dump (void) const;
+ // Dump the state of an object.
+
+ ACE_ALLOC_HOOK_DECLARE;
+ // Declare the dynamic allocation hooks.
+
+private:
+ struct sigaction sa_;
+ // Controls signal behavior.
+};
+
+class ACE_Export ACE_Sig_Guard
+ // = TITLE
+ // Hold signals in MASK for duration of a C++ statement block.
+ // Note that a "0" for mask causes all signals to be held.
+{
+public:
+ // = Set/remove mask.
+ ACE_Sig_Guard (ACE_Sig_Set *mask = 0);
+ ~ACE_Sig_Guard (void);
+
+ void dump (void) const;
+ // Dump the state of an object.
+
+ ACE_ALLOC_HOOK_DECLARE;
+ // Declare the dynamic allocation hooks.
+
+private:
+ ACE_Sig_Set omask_;
+ // Original signal mask.
+};
+
+class ACE_Export ACE_Sig_Handler
+ // = TITLE
+ // 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.
+ //
+ // = DESCRIPTION
+ // 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.
+{
+public:
+ // = Registration and removal 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);
+ // 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.
+
+ virtual int remove_handler (int signum,
+ ACE_Sig_Action *new_disp = 0,
+ ACE_Sig_Action *old_disp = 0,
+ int sigkey = -1);
+ // 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.
+
+ // Set/get signal status.
+ static sig_atomic_t sig_pending (void);
+ // True if there is a pending signal.
+
+ static void sig_pending (sig_atomic_t);
+ // Reset the value of <sig_pending_> so that no signal is pending.
+
+ // = Set/get the handler associated with a particular signal.
+
+ virtual ACE_Event_Handler *handler (int signum);
+ // Return the list of <ACE_Sig_Handlers> associated with <signum>.
+
+ virtual ACE_Event_Handler *handler (int signum, ACE_Event_Handler *);
+ // Set a new <ACE_Event_Handler> that is associated with <signum>.
+ // Return the existing handler.
+
+ void dump (void) const;
+ // Dump the state of an object.
+
+ ACE_ALLOC_HOOK_DECLARE;
+ // Declare the dynamic allocation hooks.
+
+protected:
+ // = These methods and data members are shared by derived classes.
+
+ static int in_range (int signum);
+ // Check whether the SIGNUM is within the legal range of signals.
+
+ static sig_atomic_t sig_pending_;
+ // Keeps track of whether a signal is pending.
+
+#if defined (ACE_MT_SAFE)
+ static ACE_Recursive_Thread_Mutex ace_sig_handler_lock_;
+#endif /* ACE_MT_SAFE */
+
+private:
+ static void dispatch (int, siginfo_t *, ucontext_t *);
+ // Callback routine registered with sigaction(2) that dispatches the
+ // handle_signal() method of the appropriate pre-registered
+ // ACE_Event_Handler.
+
+ static ACE_Event_Handler *signal_handlers_[NSIG];
+ // Array used to store one user-defined Event_Handler for every
+ // signal.
+};
+
+class ACE_Export ACE_Sig_Adapter : public ACE_Event_Handler
+ // = TITLE
+ // Provide an adapter that transforms various types of signal
+ // handlers into the scheme used by the <ACE_Reactor>.
+
+{
+public:
+ ACE_Sig_Adapter (ACE_Sig_Action &, int sigkey);
+ ACE_Sig_Adapter (ACE_Event_Handler *, int sigkey);
+ ACE_Sig_Adapter (ACE_Sig_Handler_Ex, int sigkey = 0);
+
+ int sigkey (void);
+ // Returns this signal key that's used to remove this from the
+ // <ACE_Reactor>'s internal table.
+
+ virtual int handle_signal (int, siginfo_t *, ucontext_t *);
+ // Called by the <Reactor> to dispatch the signal handler.
+
+private:
+ int sigkey_;
+ // Key for this signal handler (used to remove it).
+
+ enum
+ {
+ ACE_HANDLER, // We're just wrapping an ACE_Event_Handler.
+ SIG_ACTION, // An ACE_Sig_Action.
+ C_FUNCTION // A normal C function.
+ } type_;
+ // Is this an external handler or an ACE handler?
+
+ // = This should be a union, but C++ won't allow that because the
+ // <ACE_Sig_Action> has a constructor.
+ ACE_Sig_Action sa_;
+ // This is an external handler (ugh).
+
+ ACE_Event_Handler *eh_;
+ // This is an ACE hander.
+
+ ACE_Sig_Handler_Ex sig_func_;
+ // This is a normal C function.
+};
+
+// HPUX sucks big time!
+#if !defined (HPUX)
+class ACE_Export ACE_Sig_Handlers : public ACE_Sig_Handler
+ // = TITLE
+ // 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.
+ //
+ // = DESCRIPTION
+ // 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.
+{
+public:
+ // = Registration and removal 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);
+ // 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.
+
+ virtual int remove_handler (int signum,
+ ACE_Sig_Action *new_disp = 0,
+ ACE_Sig_Action *old_disp = 0,
+ int sigkey = -1);
+ // Remove the ACE_Event_Handler currently associated with <signum>.
+ // 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.
+
+ // = Set/get the handler associated with a particular signal.
+
+ virtual ACE_Event_Handler *handler (int signum);
+ // Return the head of the list of ACE_Sig_Handlers associated
+ // with SIGNUM.
+
+ virtual ACE_Event_Handler *handler (int signum, ACE_Event_Handler *);
+ // 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.
+
+ void dump (void) const;
+ // Dump the state of an object.
+
+ ACE_ALLOC_HOOK_DECLARE;
+ // Declare the dynamic allocation hooks.
+
+private:
+ static void dispatch (int signum, siginfo_t *, ucontext_t *);
+ // Callback routine registered with sigaction(2) that dispatches the
+ // handle_signal() method of all the pre-registered
+ // ACE_Event_Handlers for <signum>
+
+ static int sigkey_;
+ // 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.
+
+ static int third_party_sig_handler_;
+ // If this is > 0 then a 3rd party library has registered a
+ // handler...
+};
+#endif /* HPUX */
+
+#if defined (__ACE_INLINE__)
+#include "ace/Signal.i"
+#endif /* __ACE_INLINE__ */
+
+#endif /* ACE_SIGNAL_HANDLER_H */