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