#include <SigHandlers.h>
Inheritance diagram for ASSA::SigHandlers:
Public Member Functions | |
virtual int | install (int signum_, EventHandler *new_hand_, SigAction *new_disp_=0, EventHandler **old_hand_=0, SigAction *old_disp_=0) |
Register EventHandler with dispatching system. | |
virtual int | remove (int signum_, EventHandler *eh_, SigAction *new_disp_=0, SigAction *old_disp_=0) |
Remove EventHandler from the list of registered handler for signum_. | |
Static Public Member Functions | |
static void | sighandlers_dispatcher (int signum_) |
A wrapper around static SigHandlers::dispatch(). | |
Static Private Member Functions | |
static void | dispatch (int signum_) |
The heart of SigHandlers class - this callback function is really registered with OS to catch all of the signals for which event handler has been installed. |
Definition at line 55 of file SigHandlers.h.
|
The heart of SigHandlers class - this callback function is really registered with OS to catch all of the signals for which event handler has been installed. Appropriate EventHandler(s) are then notified. Reimplemented from ASSA::SigHandler. Definition at line 237 of file SigHandlers.cpp. References ASSA::SigHandlersList::begin(), ASSA::SigHandlersList::end(), ASSA::SigHandlersList::erase(), ASSA::EventHandler::handle_signal(), ASSA::SigHandlersList::instance(), ASSA::SIGHAND, and trace_with_mask. Referenced by sighandlers_dispatcher(). 00238 { 00239 trace_with_mask("SigHandlers::dispatch", SIGHAND); 00240 00241 /*--- 00242 For every element in the set that holds all EventHandlers for 00243 given signum, call its respective handle_signal() member function. 00244 ---*/ 00245 00246 /*--- save errno ---*/ 00247 int errno_saved = errno; 00248 00249 SigHandlersList& handlist = *(SigHandlersList::instance(signum_)); 00250 SigHandlersList::iterator it; 00251 EventHandler* ehp; 00252 00253 for (it=handlist.begin(); it != handlist.end(); it++) { 00254 ehp = *it; 00255 if (ehp->handle_signal (signum_) == -1) { 00256 /*--- 00257 this event handler reported error when handling 00258 signum - remove it from the set 00259 ---*/ 00260 handlist.erase (it); 00261 } 00262 } 00263 /*--- restore errno ---*/ 00264 errno = errno_saved; 00265 }
|
|
Register EventHandler with dispatching system.
Reimplemented from ASSA::SigHandler. Definition at line 36 of file SigHandlers.cpp. References ASSA::ASSAERR, ASSA::SigHandlersList::cfunc_handler(), DL, EL, ASSA::SigAction::handler(), ASSA::SigHandler::in_range(), ASSA::SigHandlersList::insert(), ASSA::SigHandlersList::instance(), ASSA::SigAction::retrieve_action(), ASSA::SIGHAND, sighandlers_dispatcher(), and trace_with_mask. 00041 { 00042 /* 00043 Retrieve current signal disposition. If 3rd party handler has 00044 already been istalled, make CFUNC_Handler out of it, and put it in 00045 the list with id=0. 00046 00047 Add new_hand_ to the list. Has global sighandlers_dispatcher not 00048 been installed yet, install it too. 00049 */ 00050 00051 trace_with_mask("SigHandlers::install()", SIGHAND); 00052 00053 if (!in_range(signum_) == -1) { 00054 EL((ASSAERR,"in_range (%s) failed\n",signum_)); 00055 return -1; 00056 } 00057 00058 CFUNC_Handler* cfhp = NULL; 00059 SigHandlersList* handlist = NULL; 00060 00061 handlist = SigHandlersList::instance(signum_); 00062 00063 /*--- Retrieve current signal disposition ---*/ 00064 00065 SigAction cd; 00066 cd.retrieve_action(signum_); 00067 00068 /* 00069 Check whether 3rd party software has already installed 00070 signal handler. 00071 */ 00072 if ( cd.handler() != (C_SIG_HANDLER) sighandlers_dispatcher && 00073 cd.handler() != SIG_IGN && 00074 cd.handler() != SIG_DFL ) 00075 { 00076 /* 00077 Looks like some other code got ahead of me and installed C-function 00078 signal handler. Make a note of it. 00079 00080 Create EventHandler to hold 3rd party handler. This handler will be 00081 deleted only by SigHandlers::remove (NULL), when application demanded 00082 to remove all of the handlers. 00083 */ 00084 DL((SIGHAND,"Detected 3rd party \"C\" handler!\n")); 00085 00086 cfhp = new CFUNC_Handler (cd.handler ()); 00087 handlist->cfunc_handler (cfhp); 00088 00089 /* 00090 Insert 3rd party handler in list of handlers 00091 for this signal. 00092 */ 00093 DL((SIGHAND,"Adding 3rd party \"C\" handler\n")); 00094 00095 if ( handlist->insert (cfhp) == false ) { 00096 EL((ASSAERR, "Failed to insert "\ 00097 "c_func_handler for signum %d\n", signum_)); 00098 delete (cfhp); 00099 handlist->cfunc_handler (0); 00100 return -1; 00101 } 00102 DL((SIGHAND,"Set size: %d\n", handlist->size () )); 00103 } 00104 /*--- Add new_hand_ to the list of handlers for signum_. ---*/ 00105 00106 DL((SIGHAND,"Adding EventHandler to the list\n")); 00107 00108 if (handlist->insert (new_hand_) == false) { 00109 /*--- 00110 I failed to install new handler and might have already 00111 added 3rd party CFUNC_Handler to the list without altering 00112 disposition - if that's true, clean up the list. 00113 ---*/ 00114 EL((ASSAERR,"failed to add new_hand_ to handlers list\n")); 00115 00116 if (handlist->seen_cfunc_handler () && 00117 handlist->size() == 1) 00118 { 00119 handlist->erase (); 00120 handlist->cfunc_handler (0); 00121 } 00122 return -1; 00123 } 00124 DL((SIGHAND,"Set size: %d\n", handlist->size () )); 00125 00126 /*--- Has sighandlers_dispatcher been already installed? ---*/ 00127 00128 if (cd.handler() == (C_SIG_HANDLER) sighandlers_dispatcher) { 00129 return 0; 00130 } 00131 DL((SIGHAND,"Installing 'sighandlers_dispatcher'\n")); 00132 00133 /* 00134 Installing new disposition; if user forgot to give me one 00135 then default will be used. 00136 */ 00137 SigAction sa ((C_SIG_HANDLER) SIG_DFL); 00138 00139 if (new_disp_ == 0) { 00140 new_disp_ = &sa; 00141 } 00142 00143 new_disp_->handler ((C_SIG_HANDLER) sighandlers_dispatcher); 00144 00145 if (new_disp_->register_action (signum_, old_disp_) == -1) { 00146 /*--- 00147 I failed to install sighandlers_dispatcher. Up to this 00148 point, if application had conventional C handler installed, 00149 it still remains active. Handlers list built so far is 00150 meaningless - get rid of it. ---*/ 00151 00152 EL((ASSAERR,"register_action() error\n")); 00153 00154 if (handlist->seen_cfunc_handler ()) { 00155 handlist->erase (); 00156 handlist->cfunc_handler (0); 00157 delete cfhp; 00158 } 00159 handlist->erase (new_hand_); 00160 return -1; 00161 } 00162 return 0; 00163 }
|
|
Remove EventHandler from the list of registered handler for signum_. If eh_ is NULL, then all EventHandler(s) will be removed from the list, and object will go back to passive mode in which no signal handling is done via SigHandlers class dispatcher. If new_disp_ is omitted, SIG_DFL will be used instead.
Reimplemented from ASSA::SigHandler. Definition at line 167 of file SigHandlers.cpp. References ASSA::ASSAERR, DL, EL, ASSA::SigHandlersList::end(), ASSA::SigHandlersList::erase(), ASSA::SigHandlersList::find(), ASSA::SigHandler::in_range(), ASSA::SigHandlersList::instance(), ASSA::SIGHAND, ASSA::SigHandlersList::size(), and trace_with_mask. 00170 { 00171 trace_with_mask("SigHandlers::remove()", SIGHAND); 00172 00173 if (in_range (signum_)) { 00174 EL((ASSAERR, "singum_ %d is out of range\n", signum_)); 00175 return -1; 00176 } 00177 00178 CFUNC_Handler* Cfhp = NULL; // pointer to C-function event handler 00179 EventHandler* ehp = NULL; // pointer to current event handler 00180 00181 SigHandlersList& handlist = *(SigHandlersList::instance(signum_)); 00182 00183 if (eh_ == NULL) { 00184 DL((SIGHAND,"Erasing the entire set\n")); 00185 /*--- Erase an entire list. ---*/ 00186 handlist.erase (); 00187 DL((SIGHAND,"Set size: %d\n", handlist.size ())); 00188 } 00189 else { 00190 /* 00191 Note: I cannot do erasure in the same loop for following reason: 00192 00193 According to Stroustrup (Section 17.4.1.7): 00194 "After erase(), the iterator cannot be used again because 00195 the element to which it pointed is no longer there." 00196 00197 According to STL Tutorial and Ref. Guide: 00198 "The erase function invalidates all iterators to all 00199 positions past the point of erasure." 00200 00201 That's why here we first take care of id recycling and heap memory 00202 deallocation, and only then clean() the map all at once. 00203 */ 00204 SigHandlersList::iterator it; 00205 00206 if ((it = handlist.find (eh_)) != handlist.end ()) { 00207 DL((SIGHAND,"Removing EventHandler\n")); 00208 ehp = (*it); 00209 handlist.erase (it); 00210 } 00211 DL((SIGHAND,"Set size: %d\n", handlist.size () )); 00212 } 00213 /*--- If set is not empty, we're done ---*/ 00214 if (handlist.size ()) return 0; 00215 00216 /* If map was emptied out, install new disposition 00217 with the 3rd party "C" function handler, if we had it. 00218 */ 00219 SigAction null_sa; 00220 if (new_disp_ == 0) new_disp_ = &null_sa; 00221 00222 DL((SIGHAND,"Handlers List is empty\n")); 00223 00224 if (handlist.seen_cfunc_handler ()) { 00225 /*--- Put 3rd party handler into disposition ---*/ 00226 DL((SIGHAND,"Reinstalling \"C\" handler\n")); 00227 Cfhp = handlist.cfunc_handler (0); 00228 new_disp_->handler (Cfhp->handler ()); 00229 delete Cfhp; 00230 } 00231 /*--- Install new disposition ---*/ 00232 return new_disp_->register_action (signum_, old_disp_); 00233 }
|
|
A wrapper around static SigHandlers::dispatch(). It is needed for the purpose of differentiation it with other signal handlers that might be installed by user's code.
Definition at line 26 of file SigHandlers.cpp. References dispatch(), DL, ASSA::SIGHAND, and trace_with_mask. Referenced by install(). 00027 { 00028 trace_with_mask("SigHandlers::sighandlers_dispatch", SIGHAND); 00029 00030 DL((SIGHAND,"==> Recevied signal # %d\n", signum_)); 00031 dispatch (signum_); 00032 }
|