Signal.h

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 
00003 //=============================================================================
00004 /**
00005  *  @file    Signal.h
00006  *
00007  *  Signal.h,v 4.53 2006/02/23 09:00:18 jwillemsen Exp
00008  *
00009  *  @author Douglas C. Schmidt <schmidt@cs.wustl.edu>
00010  */
00011 //=============================================================================
00012 
00013 #ifndef ACE_SIGNAL_HANDLER_H
00014 #define ACE_SIGNAL_HANDLER_H
00015 #include /**/ "ace/pre.h"
00016 
00017 #include "ace/config-lite.h"
00018 
00019 #if defined (ACE_DONT_INCLUDE_ACE_SIGNAL_H)
00020 # error ace/Signal.h was #included instead of signal.h by ace/OS_NS_signal.h:  fix!!!!
00021 #endif /* ACE_DONT_INCLUDE_ACE_SIGNAL_H */
00022 
00023 #include "ace/ACE_export.h"
00024 
00025 #if !defined (ACE_LACKS_PRAGMA_ONCE)
00026 # pragma once
00027 #endif /* ACE_LACKS_PRAGMA_ONCE */
00028 
00029 #include "ace/os_include/os_signal.h"
00030 #include "ace/Event_Handler.h"
00031 
00032 // Type of the extended signal handler.
00033 typedef void (*ACE_Sig_Handler_Ex) (int, siginfo_t *siginfo, ucontext_t *ucontext);
00034 
00035 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00036 
00037 /**
00038  * @class ACE_Sig_Set
00039  *
00040  * @brief Provide a C++ wrapper for the C sigset_t interface.
00041  *
00042  * Handle signals via a more elegant C++ interface (e.g.,
00043  * doesn't require the use of global variables or global
00044  * functions in an application).
00045  */
00046 class ACE_Export ACE_Sig_Set
00047 {
00048 public:
00049   // = Initialization and termination methods.
00050   /// Initialize <sigset_> with @a sigset.  If @a sigset == 0 then fill
00051   /// the set.
00052   ACE_Sig_Set (sigset_t *sigset);
00053 
00054   /// Initialize <sigset_> with @a sigset.  If @a sigset == 0 then fill
00055   /// the set.
00056   ACE_Sig_Set (ACE_Sig_Set *sigset);
00057 
00058   /// If @a fill == 0 then initialize the <sigset_> to be empty, else
00059   /// full.
00060   ACE_Sig_Set (int fill = 0);
00061 
00062   ~ACE_Sig_Set (void);
00063 
00064   /// Create a set that excludes all signals defined by the system.
00065   int empty_set (void);
00066 
00067   /// Create a set that includes all signals defined by the system.
00068   int fill_set (void);
00069 
00070   /// Adds the individual signal specified by <signo> to the set.
00071   int sig_add (int signo);
00072 
00073   /// Deletes the individual signal specified by <signo> from the set.
00074   int sig_del (int signo);
00075 
00076   /// Checks whether the signal specified by <signo> is in the set.
00077   int is_member (int signo) const;
00078 
00079   /// Returns a pointer to the underlying <sigset_t>.
00080   operator sigset_t *();
00081 
00082   /// Returns a copy of the underlying <sigset_t>.
00083   sigset_t sigset (void) const;
00084 
00085   /// Dump the state of an object.
00086   void dump (void) const;
00087 
00088   /// Declare the dynamic allocation hooks.
00089   ACE_ALLOC_HOOK_DECLARE;
00090 
00091 private:
00092   /// Set of signals.
00093   sigset_t sigset_;
00094 };
00095 
00096 /**
00097  * @class ACE_Sig_Action
00098  *
00099  * @brief C++ wrapper facade for the <sigaction> struct.
00100  */
00101 class ACE_Export ACE_Sig_Action
00102 {
00103 public:
00104   // = Initialization methods.
00105   /// Default constructor.  Initializes everything to 0.
00106   ACE_Sig_Action (void);
00107 
00108   /// Assigns the various fields of a <sigaction> struct but doesn't
00109   /// register for signal handling via the <sigaction> function.
00110   ACE_Sig_Action (ACE_SignalHandler handler,
00111                   sigset_t *sigmask = 0,
00112                   int flags = 0);
00113 
00114   /// Assigns the various fields of a <sigaction> struct but doesn't
00115   /// register for signal handling via the <sigaction> function.
00116   ACE_Sig_Action (ACE_SignalHandler handler,
00117                   const ACE_Sig_Set &sigmask,
00118                   int flags = 0);
00119 
00120   /**
00121    * Assigns the various fields of a <sigaction> struct and registers
00122    * the <handler> to process signal <signum> via the <sigaction>
00123    * function.
00124    */
00125   ACE_Sig_Action (ACE_SignalHandler handler,
00126                   int signum,
00127                   sigset_t *sigmask = 0,
00128                   int flags = 0);
00129 
00130   /**
00131    * Assigns the various fields of a <sigaction> struct and registers
00132    * the <handler> to process signal <signum> via the <sigaction>
00133    * function.
00134    */
00135   ACE_Sig_Action (ACE_SignalHandler handler,
00136                   int signum,
00137                   const ACE_Sig_Set &sigmask,
00138                   int flags = 0);
00139 
00140 
00141   // @@ The next two methods have a parameter as "signalss". Please do
00142   // not change the argument name as "signals". This causes the
00143   // following problem as reported by
00144   // <James.Briggs@dsto.defence.gov.au>.
00145 
00146   // In the file Signal.h two of the functions have and argument name
00147   // of signals. signals is a Qt macro (to do with their meta object
00148   // stuff.
00149   // We could as well have it as "signal", but I am nost sure whether
00150   // that would cause a problem with something else - Bala <bala@cs>
00151 
00152   /**
00153    * Assigns the various fields of a <sigaction> struct and registers
00154    * the <handler> to process all <signals> via the <sigaction>
00155    * function.
00156    */
00157   ACE_Sig_Action (const ACE_Sig_Set &signalss,
00158                   ACE_SignalHandler handler,
00159                   const ACE_Sig_Set &sigmask,
00160                   int flags = 0);
00161 
00162   /**
00163    * Assigns the various fields of a <sigaction> struct and registers
00164    * the <handler> to process all <signals> via the <sigaction>
00165    * function.
00166    */
00167   ACE_Sig_Action (const ACE_Sig_Set &signalss,
00168                   ACE_SignalHandler handler,
00169                   sigset_t *sigmask = 0,
00170                   int flags = 0);
00171 
00172   /// Copy constructor.
00173   ACE_Sig_Action (const ACE_Sig_Action &s);
00174 
00175   /// Default dtor.
00176   ~ACE_Sig_Action (void);
00177 
00178   // = Signal action management.
00179   /// Register <this> as the current disposition and store old
00180   /// disposition into <oaction> if it is non-NULL.
00181   int register_action (int signum,
00182                        ACE_Sig_Action *oaction = 0);
00183 
00184   /// Assign the value of <oaction> to <this> and make it become the
00185   /// new signal disposition.
00186   int restore_action (int signum,
00187                       ACE_Sig_Action &oaction);
00188 
00189   /// Retrieve the current disposition into <this>.
00190   int retrieve_action (int signum);
00191 
00192   /// Set current signal action.
00193   void set (struct sigaction *);
00194 
00195   /// Get current signal action.
00196   struct sigaction *get (void);
00197   operator struct sigaction *();
00198 
00199   /// Set current signal flags.
00200   void flags (int);
00201 
00202   /// Get current signal flags.
00203   int flags (void);
00204 
00205   /// Set current signal mask.
00206   void mask (sigset_t *);
00207   void mask (ACE_Sig_Set &);
00208 
00209   /// Get current signal mask.
00210   sigset_t *mask (void);
00211 
00212   /// Set current signal handler (pointer to function).
00213   void handler (ACE_SignalHandler);
00214 
00215   /// Get current signal handler (pointer to function).
00216   ACE_SignalHandler handler (void);
00217 
00218   /// Dump the state of an object.
00219   void dump (void) const;
00220 
00221   /// Declare the dynamic allocation hooks.
00222   ACE_ALLOC_HOOK_DECLARE;
00223 
00224 private:
00225   /// Controls signal behavior.
00226   struct sigaction sa_;
00227 };
00228 
00229 /**
00230  * @class ACE_Sig_Guard
00231  *
00232  * @brief Hold signals in MASK for duration of a C++ statement block.
00233  * Note that a "0" for mask causes all signals to be held.
00234  */
00235 class ACE_Export ACE_Sig_Guard
00236 {
00237 public:
00238   // = Initialization and termination methods.
00239   /// This is kind of conditional Guard, needed when guard should be
00240   /// activated only when a spcific condition met. When condition ==
00241   /// true (default), Guard is activated
00242   ACE_Sig_Guard (ACE_Sig_Set *mask = 0, bool condition = true);
00243 
00244   /// Restore blocked signals.
00245   ~ACE_Sig_Guard (void);
00246 
00247   /// Dump the state of an object.
00248   void dump (void) const;
00249 
00250   /// Declare the dynamic allocation hooks.
00251   ACE_ALLOC_HOOK_DECLARE;
00252 
00253 private:
00254   /// Original signal mask.
00255   ACE_Sig_Set omask_;
00256 
00257   /// Guard Condition
00258   bool condition_;
00259 };
00260 
00261 /**
00262  * @class ACE_Sig_Handler
00263  *
00264  * @brief This is the main dispatcher of signals for ACE.  It improves
00265  * the existing UNIX signal handling mechanism by allowing C++
00266  * objects to handle signals in a way that avoids the use of
00267  * global/static variables and functions.
00268  *
00269  * Using this class a program can register an ACE_Event_Handler
00270  * with the ACE_Sig_Handler in order to handle a designated
00271  * <signum>.  When a signal occurs that corresponds to this
00272  * <signum>, the <handle_signal> method of the registered
00273  * ACE_Event_Handler is invoked automatically.
00274  */
00275 class ACE_Export ACE_Sig_Handler
00276 {
00277 public:
00278   /// Default ctor/dtor.
00279   ACE_Sig_Handler (void);
00280   virtual ~ACE_Sig_Handler (void);
00281 
00282   // = Registration and removal methods.
00283   /**
00284    * Add a new ACE_Event_Handler and a new sigaction associated with
00285    * <signum>.  Passes back the existing ACE_Event_Handler and its
00286    * sigaction if pointers are non-zero.  Returns -1 on failure and >=
00287    * 0 on success.
00288    */
00289   virtual int register_handler (int signum,
00290                                 ACE_Event_Handler *new_sh,
00291                                 ACE_Sig_Action *new_disp = 0,
00292                                 ACE_Event_Handler **old_sh = 0,
00293                                 ACE_Sig_Action *old_disp = 0);
00294 
00295   /**
00296    * Remove the ACE_Event_Handler currently associated with
00297    * <signum>.  <sigkey> is ignored in this implementation since there
00298    * is only one instance of a signal handler.  Install the new
00299    * disposition (if given) and return the previous disposition (if
00300    * desired by the caller).  Returns 0 on success and -1 if <signum>
00301    * is invalid.
00302    */
00303   virtual int remove_handler (int signum,
00304                               ACE_Sig_Action *new_disp = 0,
00305                               ACE_Sig_Action *old_disp = 0,
00306                               int sigkey = -1);
00307 
00308   // Set/get signal status.
00309   /// True if there is a pending signal.
00310   static int sig_pending (void);
00311 
00312   /// Reset the value of <sig_pending_> so that no signal is pending.
00313   static void sig_pending (int);
00314 
00315   // = Set/get the handler associated with a particular signal.
00316 
00317   /// Return the ACE_Sig_Handler associated with <signum>.
00318   virtual ACE_Event_Handler *handler (int signum);
00319 
00320   /// Set a new ACE_Event_Handler that is associated with <signum>.
00321   /// Return the existing handler.
00322   virtual ACE_Event_Handler *handler (int signum,
00323                                       ACE_Event_Handler *);
00324 
00325   /**
00326    * Callback routine registered with sigaction(2) that dispatches the
00327    * <handle_signal> method of the appropriate pre-registered
00328    * ACE_Event_Handler.
00329    */
00330   static void dispatch (int, siginfo_t *,
00331                         ucontext_t *);
00332 
00333   /// Dump the state of an object.
00334   void dump (void) const;
00335 
00336   /// Declare the dynamic allocation hooks.
00337   ACE_ALLOC_HOOK_DECLARE;
00338 
00339 protected:
00340   // = These methods and data members are shared by derived classes.
00341 
00342   /**
00343    * Set a new ACE_Event_Handler that is associated with <signum>.
00344    * Return the existing handler.  Does not acquire any locks so that
00345    * it can be called from a signal handler, such as <dispatch>.
00346    */
00347   static ACE_Event_Handler *handler_i (int signum,
00348                                        ACE_Event_Handler *);
00349 
00350   /**
00351    * This implementation method is called by <register_handler> and
00352    * <dispatch>.  It doesn't do any locking so that it can be called
00353    * within a signal handler, such as <dispatch>.  It adds a new
00354    * ACE_Event_Handler and a new sigaction associated with <signum>.
00355    * Passes back the existing ACE_Event_Handler and its sigaction if
00356    * pointers are non-zero.  Returns -1 on failure and >= 0 on
00357    * success.
00358    */
00359   static int register_handler_i (int signum,
00360                                  ACE_Event_Handler *new_sh,
00361                                  ACE_Sig_Action *new_disp = 0,
00362                                  ACE_Event_Handler **old_sh = 0,
00363                                  ACE_Sig_Action *old_disp = 0);
00364 
00365   /// Check whether the SIGNUM is within the legal range of signals.
00366   static int in_range (int signum);
00367 
00368   /// Keeps track of whether a signal is pending.
00369   static sig_atomic_t sig_pending_;
00370 
00371 private:
00372   /// Array used to store one user-defined Event_Handler for every
00373   /// signal.
00374   static ACE_Event_Handler *signal_handlers_[ACE_NSIG];
00375 };
00376 
00377 /**
00378  * @class ACE_Sig_Adapter
00379  *
00380  * @brief Provide an adapter that transforms various types of signal
00381  * handlers into the scheme used by the ACE_Reactor.
00382  */
00383 class ACE_Export ACE_Sig_Adapter : public ACE_Event_Handler
00384 {
00385 public:
00386   ACE_Sig_Adapter (ACE_Sig_Action &, int sigkey);
00387   ACE_Sig_Adapter (ACE_Event_Handler *, int sigkey);
00388   ACE_Sig_Adapter (ACE_Sig_Handler_Ex, int sigkey = 0);
00389   ~ACE_Sig_Adapter (void);
00390 
00391   /// Returns this signal key that's used to remove this from the
00392   /// ACE_Reactor's internal table.
00393   int sigkey (void);
00394 
00395   /// Called by the <Reactor> to dispatch the signal handler.
00396   virtual int handle_signal (int, siginfo_t *, ucontext_t *);
00397 
00398 private:
00399   /// Key for this signal handler (used to remove it).
00400   int sigkey_;
00401 
00402   /// Is this an external handler or an ACE handler?
00403   enum
00404   {
00405     /// We're just wrapping an ACE_Event_Handler.
00406     ACE_HANDLER,
00407     /// An ACE_Sig_Action.
00408     SIG_ACTION,
00409     /// A normal C function.
00410     C_FUNCTION
00411   } type_;
00412 
00413   // = This should be a union, but C++ won't allow that because the
00414   // <ACE_Sig_Action> has a constructor.
00415   /// This is an external handler (ugh).
00416   ACE_Sig_Action sa_;
00417 
00418   /// This is an ACE hander.
00419   ACE_Event_Handler *eh_;
00420 
00421   /// This is a normal C function.
00422   ACE_Sig_Handler_Ex sig_func_;
00423 };
00424 
00425 #if !defined (ACE_HAS_BROKEN_HPUX_TEMPLATES)
00426 /**
00427  * @class ACE_Sig_Handlers
00428  *
00429  * @brief This is an alternative signal handling dispatcher for ACE.  It
00430  * allows a list of signal handlers to be registered for each
00431  * signal.  It also makes SA_RESTART the default mode.
00432  *
00433  * Using this class a program can register one or more
00434  * ACE_Event_Handler with the ACE_Sig_Handler in order to
00435  * handle a designated <signum>.  When a signal occurs that
00436  * corresponds to this <signum>, the <handle_signal> methods of
00437  * all the registered ACE_Event_Handlers are invoked
00438  * automatically.
00439  */
00440 class ACE_Export ACE_Sig_Handlers : public ACE_Sig_Handler
00441 {
00442 public:
00443   // = Registration and removal methods.
00444   /**
00445    * Add a new ACE_Event_Handler and a new sigaction associated with
00446    * <signum>.  Passes back the existing ACE_Event_Handler and its
00447    * sigaction if pointers are non-zero.  Returns -1 on failure and
00448    * a <sigkey> that is >= 0 on success.
00449    */
00450   virtual int register_handler (int signum,
00451                                 ACE_Event_Handler *new_sh,
00452                                 ACE_Sig_Action *new_disp = 0,
00453                                 ACE_Event_Handler **old_sh = 0,
00454                                 ACE_Sig_Action *old_disp = 0);
00455 
00456   /**
00457    * Remove an ACE_Event_Handler currently associated with <signum>.
00458    * We remove the handler if (1) its <sigkey> matches the <sigkey>
00459    * passed as a parameter or (2) if we've been told to remove all the
00460    * handlers, i.e., <sigkey> == -1.  If a new disposition is given it
00461    * is installed and the previous disposition is returned (if desired
00462    * by the caller).  Returns 0 on success and -1 if <signum> is
00463    * invalid.
00464    */
00465   virtual int remove_handler (int signum,
00466                               ACE_Sig_Action *new_disp = 0,
00467                               ACE_Sig_Action *old_disp = 0,
00468                               int sigkey = -1);
00469 
00470   // = Set/get the handler associated with a particular signal.
00471 
00472   /// Return the head of the list of ACE_Sig_Handlers associated with
00473   /// SIGNUM.
00474   virtual ACE_Event_Handler *handler (int signum);
00475 
00476   /**
00477    * Set a new ACE_Event_Handler that is associated with SIGNUM at
00478    * the head of the list of signals.  Return the existing handler
00479    * that was at the head.
00480    */
00481   virtual ACE_Event_Handler *handler (int signum,
00482                                       ACE_Event_Handler *);
00483 
00484   /**
00485    * Callback routine registered with sigaction(2) that dispatches the
00486    * <handle_signal> method of all the pre-registered
00487    * ACE_Event_Handlers for <signum>
00488    */
00489   static void dispatch (int signum, siginfo_t *, ucontext_t *);
00490 
00491   /// Dump the state of an object.
00492   void dump (void) const;
00493 
00494   /// Declare the dynamic allocation hooks.
00495   ACE_ALLOC_HOOK_DECLARE;
00496 
00497 private:
00498   /**
00499    * Keeps track of the id that uniquely identifies each registered
00500    * signal handler.  This id can be used to cancel a timer via the
00501    * <remove_handler> method.
00502    */
00503   static int sigkey_;
00504 
00505   /// If this is > 0 then a 3rd party library has registered a
00506   /// handler...
00507   static int third_party_sig_handler_;
00508 };
00509 #endif /* ACE_HAS_BROKEN_HPUX_TEMPLATES */
00510 
00511 ACE_END_VERSIONED_NAMESPACE_DECL
00512 
00513 #if defined (__ACE_INLINE__)
00514 #include "ace/Signal.inl"
00515 #endif /* __ACE_INLINE__ */
00516 
00517 #include /**/ "ace/post.h"
00518 #endif /* ACE_SIGNAL_HANDLER_H */

Generated on Thu Nov 9 09:42:03 2006 for ACE by doxygen 1.3.6