00001 // -*- C++ -*- 00002 00003 //============================================================================= 00004 /** 00005 * @file Sig_Handler.h 00006 * 00007 * $Id: Sig_Handler.h 78716 2007-07-02 09:42:02Z johnnyw $ 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/ACE_export.h" 00018 00019 #if !defined (ACE_LACKS_PRAGMA_ONCE) 00020 # pragma once 00021 #endif /* ACE_LACKS_PRAGMA_ONCE */ 00022 00023 #include "ace/Event_Handler.h" 00024 00025 ACE_BEGIN_VERSIONED_NAMESPACE_DECL 00026 00027 class ACE_Sig_Action; 00028 00029 /** 00030 * @class ACE_Sig_Handler 00031 * 00032 * @brief This is the main dispatcher of signals for ACE. It improves 00033 * the existing UNIX signal handling mechanism by allowing C++ 00034 * objects to handle signals in a way that avoids the use of 00035 * global/static variables and functions. 00036 * 00037 * Using this class a program can register an ACE_Event_Handler 00038 * with the ACE_Sig_Handler in order to handle a designated 00039 * @a signum. When a signal occurs that corresponds to this 00040 * @a signum, the @c handle_signal method of the registered 00041 * ACE_Event_Handler is invoked automatically. 00042 */ 00043 class ACE_Export ACE_Sig_Handler 00044 { 00045 public: 00046 /// Default ctor/dtor. 00047 ACE_Sig_Handler (void); 00048 virtual ~ACE_Sig_Handler (void); 00049 00050 // = Registration and removal methods. 00051 /** 00052 * Add a new ACE_Event_Handler and a new sigaction associated with 00053 * @a signum. Passes back the existing ACE_Event_Handler and its 00054 * sigaction if pointers are non-zero. Returns -1 on failure and >= 00055 * 0 on success. 00056 */ 00057 virtual int register_handler (int signum, 00058 ACE_Event_Handler *new_sh, 00059 ACE_Sig_Action *new_disp = 0, 00060 ACE_Event_Handler **old_sh = 0, 00061 ACE_Sig_Action *old_disp = 0); 00062 00063 /** 00064 * Remove the ACE_Event_Handler currently associated with 00065 * @a signum. @a sigkey is ignored in this implementation since there 00066 * is only one instance of a signal handler. Install the new 00067 * disposition (if given) and return the previous disposition (if 00068 * desired by the caller). Returns 0 on success and -1 if @a signum 00069 * is invalid. 00070 */ 00071 virtual int remove_handler (int signum, 00072 ACE_Sig_Action *new_disp = 0, 00073 ACE_Sig_Action *old_disp = 0, 00074 int sigkey = -1); 00075 00076 // Set/get signal status. 00077 /// True if there is a pending signal. 00078 static int sig_pending (void); 00079 00080 /// Reset the value of <sig_pending_> so that no signal is pending. 00081 static void sig_pending (int); 00082 00083 // = Set/get the handler associated with a particular signal. 00084 00085 /// Return the <ACE_Sig_Handler> associated with @a signum. 00086 virtual ACE_Event_Handler *handler (int signum); 00087 00088 /// Set a new ACE_Event_Handler that is associated with @a signum. 00089 /// Return the existing handler. 00090 virtual ACE_Event_Handler *handler (int signum, 00091 ACE_Event_Handler *); 00092 00093 /** 00094 * Callback routine registered with sigaction(2) that dispatches the 00095 * <handle_signal> method of the appropriate pre-registered 00096 * ACE_Event_Handler. 00097 */ 00098 static void dispatch (int, siginfo_t *, 00099 ucontext_t *); 00100 00101 /// Dump the state of an object. 00102 void dump (void) const; 00103 00104 /// Declare the dynamic allocation hooks. 00105 ACE_ALLOC_HOOK_DECLARE; 00106 00107 protected: 00108 // = These methods and data members are shared by derived classes. 00109 00110 /** 00111 * Set a new ACE_Event_Handler that is associated with @a signum. 00112 * Return the existing handler. Does not acquire any locks so that 00113 * it can be called from a signal handler, such as <dispatch>. 00114 */ 00115 static ACE_Event_Handler *handler_i (int signum, 00116 ACE_Event_Handler *); 00117 00118 /** 00119 * This implementation method is called by <register_handler> and 00120 * @c dispatch. It doesn't do any locking so that it can be called 00121 * within a signal handler, such as @c dispatch. It adds a new 00122 * ACE_Event_Handler and a new sigaction associated with @a signum. 00123 * Passes back the existing ACE_Event_Handler and its sigaction if 00124 * pointers are non-zero. Returns -1 on failure and >= 0 on 00125 * success. 00126 */ 00127 static int register_handler_i (int signum, 00128 ACE_Event_Handler *new_sh, 00129 ACE_Sig_Action *new_disp = 0, 00130 ACE_Event_Handler **old_sh = 0, 00131 ACE_Sig_Action *old_disp = 0); 00132 00133 /// Check whether the SIGNUM is within the legal range of signals. 00134 static int in_range (int signum); 00135 00136 /// Keeps track of whether a signal is pending. 00137 static sig_atomic_t sig_pending_; 00138 00139 private: 00140 /// Array used to store one user-defined Event_Handler for every 00141 /// signal. 00142 static ACE_Event_Handler *signal_handlers_[ACE_NSIG]; 00143 }; 00144 00145 #if !defined (ACE_HAS_BROKEN_HPUX_TEMPLATES) 00146 /** 00147 * @class ACE_Sig_Handlers 00148 * 00149 * @brief This is an alternative signal handling dispatcher for ACE. It 00150 * allows a list of signal handlers to be registered for each 00151 * signal. It also makes SA_RESTART the default mode. 00152 * 00153 * Using this class a program can register one or more 00154 * ACE_Event_Handler with the ACE_Sig_Handler in order to 00155 * handle a designated @a signum. When a signal occurs that 00156 * corresponds to this @a signum, the <handle_signal> methods of 00157 * all the registered ACE_Event_Handlers are invoked 00158 * automatically. 00159 */ 00160 class ACE_Export ACE_Sig_Handlers : public ACE_Sig_Handler 00161 { 00162 public: 00163 // = Registration and removal methods. 00164 /** 00165 * Add a new ACE_Event_Handler and a new sigaction associated with 00166 * @a signum. Passes back the existing ACE_Event_Handler and its 00167 * sigaction if pointers are non-zero. Returns -1 on failure and 00168 * a <sigkey> that is >= 0 on success. 00169 */ 00170 virtual int register_handler (int signum, 00171 ACE_Event_Handler *new_sh, 00172 ACE_Sig_Action *new_disp = 0, 00173 ACE_Event_Handler **old_sh = 0, 00174 ACE_Sig_Action *old_disp = 0); 00175 00176 /** 00177 * Remove an ACE_Event_Handler currently associated with @a signum. 00178 * We remove the handler if (1) its <sigkey> matches the <sigkey> 00179 * passed as a parameter or (2) if we've been told to remove all the 00180 * handlers, i.e., <sigkey> == -1. If a new disposition is given it 00181 * is installed and the previous disposition is returned (if desired 00182 * by the caller). Returns 0 on success and -1 if @a signum is 00183 * invalid. 00184 */ 00185 virtual int remove_handler (int signum, 00186 ACE_Sig_Action *new_disp = 0, 00187 ACE_Sig_Action *old_disp = 0, 00188 int sigkey = -1); 00189 00190 // = Set/get the handler associated with a particular signal. 00191 00192 /// Return the head of the list of <ACE_Sig_Handler>s associated with 00193 /// SIGNUM. 00194 virtual ACE_Event_Handler *handler (int signum); 00195 00196 /** 00197 * Set a new ACE_Event_Handler that is associated with SIGNUM at 00198 * the head of the list of signals. Return the existing handler 00199 * that was at the head. 00200 */ 00201 virtual ACE_Event_Handler *handler (int signum, 00202 ACE_Event_Handler *); 00203 00204 /** 00205 * Callback routine registered with sigaction(2) that dispatches the 00206 * <handle_signal> method of all the pre-registered 00207 * ACE_Event_Handlers for @a signum 00208 */ 00209 static void dispatch (int signum, siginfo_t *, ucontext_t *); 00210 00211 /// Dump the state of an object. 00212 void dump (void) const; 00213 00214 /// Declare the dynamic allocation hooks. 00215 ACE_ALLOC_HOOK_DECLARE; 00216 00217 private: 00218 /** 00219 * Keeps track of the id that uniquely identifies each registered 00220 * signal handler. This id can be used to cancel a timer via the 00221 * <remove_handler> method. 00222 */ 00223 static int sigkey_; 00224 00225 /// If this is > 0 then a 3rd party library has registered a 00226 /// handler... 00227 static int third_party_sig_handler_; 00228 }; 00229 #endif /* ACE_HAS_BROKEN_HPUX_TEMPLATES */ 00230 00231 ACE_END_VERSIONED_NAMESPACE_DECL 00232 00233 #if defined (__ACE_INLINE__) 00234 #include "ace/Sig_Handler.inl" 00235 #endif /* __ACE_INLINE__ */ 00236 00237 #include /**/ "ace/post.h" 00238 #endif /* ACE_SIG_HANDLER_H */