00001 // -*- C++ -*- 00002 00003 //============================================================================= 00004 /** 00005 * @file Sig_Handler.h 00006 * 00007 * $Id: Sig_Handler.h 81388 2008-04-23 14:02:05Z 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 constructor. 00047 ACE_Sig_Handler (void); 00048 00049 /// Destructor 00050 virtual ~ACE_Sig_Handler (void); 00051 00052 // = Registration and removal methods. 00053 /** 00054 * Add a new ACE_Event_Handler and a new sigaction associated with 00055 * @a signum. Passes back the existing ACE_Event_Handler and its 00056 * sigaction if pointers are non-zero. Returns -1 on failure and >= 00057 * 0 on success. 00058 */ 00059 virtual int register_handler (int signum, 00060 ACE_Event_Handler *new_sh, 00061 ACE_Sig_Action *new_disp = 0, 00062 ACE_Event_Handler **old_sh = 0, 00063 ACE_Sig_Action *old_disp = 0); 00064 00065 /** 00066 * Remove the ACE_Event_Handler currently associated with 00067 * @a signum. @a sigkey is ignored in this implementation since there 00068 * is only one instance of a signal handler. Install the new 00069 * disposition (if given) and return the previous disposition (if 00070 * desired by the caller). Returns 0 on success and -1 if @a signum 00071 * is invalid. 00072 */ 00073 virtual int remove_handler (int signum, 00074 ACE_Sig_Action *new_disp = 0, 00075 ACE_Sig_Action *old_disp = 0, 00076 int sigkey = -1); 00077 00078 // Set/get signal status. 00079 /// True if there is a pending signal. 00080 static int sig_pending (void); 00081 00082 /// Reset the value of <sig_pending_> so that no signal is pending. 00083 static void sig_pending (int); 00084 00085 // = Set/get the handler associated with a particular signal. 00086 00087 /// Return the ACE_Sig_Handler associated with @a signum. 00088 virtual ACE_Event_Handler *handler (int signum); 00089 00090 /// Set a new ACE_Event_Handler that is associated with @a signum. 00091 /// Return the existing handler. 00092 virtual ACE_Event_Handler *handler (int signum, ACE_Event_Handler *); 00093 00094 /** 00095 * Callback routine registered with sigaction(2) that dispatches the 00096 * <handle_signal> method of the appropriate pre-registered 00097 * ACE_Event_Handler. 00098 */ 00099 static void dispatch (int, siginfo_t *, 00100 ucontext_t *); 00101 00102 /// Dump the state of an object. 00103 void dump (void) const; 00104 00105 /// Declare the dynamic allocation hooks. 00106 ACE_ALLOC_HOOK_DECLARE; 00107 00108 protected: 00109 // = These methods and data members are shared by derived classes. 00110 00111 /** 00112 * Set a new ACE_Event_Handler that is associated with @a signum. 00113 * Return the existing handler. Does not acquire any locks so that 00114 * it can be called from a signal handler, such as <dispatch>. 00115 */ 00116 static ACE_Event_Handler *handler_i (int signum, 00117 ACE_Event_Handler *); 00118 00119 /** 00120 * This implementation method is called by <register_handler> and 00121 * @c dispatch. It doesn't do any locking so that it can be called 00122 * within a signal handler, such as @c dispatch. It adds a new 00123 * ACE_Event_Handler and a new sigaction associated with @a signum. 00124 * Passes back the existing ACE_Event_Handler and its sigaction if 00125 * pointers are non-zero. Returns -1 on failure and >= 0 on 00126 * success. 00127 */ 00128 static int register_handler_i (int signum, 00129 ACE_Event_Handler *new_sh, 00130 ACE_Sig_Action *new_disp = 0, 00131 ACE_Event_Handler **old_sh = 0, 00132 ACE_Sig_Action *old_disp = 0); 00133 00134 /// Check whether the SIGNUM is within the legal range of signals. 00135 static int in_range (int signum); 00136 00137 /// Keeps track of whether a signal is pending. 00138 static sig_atomic_t sig_pending_; 00139 00140 private: 00141 /// Array used to store one user-defined Event_Handler for every 00142 /// signal. 00143 static ACE_Event_Handler *signal_handlers_[ACE_NSIG]; 00144 }; 00145 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 @a 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 true then a 3rd party library has registered a 00226 /// handler... 00227 static bool third_party_sig_handler_; 00228 }; 00229 00230 ACE_END_VERSIONED_NAMESPACE_DECL 00231 00232 #if defined (__ACE_INLINE__) 00233 #include "ace/Sig_Handler.inl" 00234 #endif /* __ACE_INLINE__ */ 00235 00236 #include /**/ "ace/post.h" 00237 #endif /* ACE_SIG_HANDLER_H */