Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members   Related Pages  

Signal.h

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

Generated on Mon Jun 16 11:21:15 2003 for ACE by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002