libassa 3.5.1
Loading...
Searching...
No Matches
Public Member Functions | Static Public Member Functions | Static Private Member Functions | List of all members
ASSA::SigHandlers Class Reference

#include <SigHandlers.h>

Inheritance diagram for ASSA::SigHandlers:
ASSA::SigHandler

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_.
 
- Public Member Functions inherited from ASSA::SigHandler
virtual ~SigHandler ()
 No-op virtual destructor.
 
EventHandlerhandler (int signum_, EventHandler *new_)
 Set new event handler for signal signum_ and return an existing one.
 
EventHandlerhandler (int signum_)
 Retrieve current event handler for signum_.
 

Static Public Member Functions

static void sighandlers_dispatcher (int signum_)
 A wrapper around static SigHandlers::dispatch().
 
- Static Public Member Functions inherited from ASSA::SigHandler
static void dispatch (int signum_)
 Here is the heart of SigHandler class.
 

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.
 

Additional Inherited Members

- Protected Member Functions inherited from ASSA::SigHandler
int in_range (int signum_)
 Check that signum_ is in valid range.
 

Detailed Description

Definition at line 55 of file SigHandlers.h.

Member Function Documentation

◆ dispatch()

void SigHandlers::dispatch ( int  signum_)
staticprivate

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.

Definition at line 236 of file SigHandlers.cpp.

238{
239 trace_with_mask("SigHandlers::dispatch", SIGHAND);
240
241 /*---
242 For every element in the set that holds all EventHandlers for
243 given signum, call its respective handle_signal() member function.
244 ---*/
245
246 /*--- save errno ---*/
247 int errno_saved = errno;
248
252
253 for (it=handlist.begin(); it != handlist.end(); it++) {
254 ehp = *it;
255 if (ehp->handle_signal (signum_) == -1) {
256 /*---
257 this event handler reported error when handling
258 signum - remove it from the set
259 ---*/
260 handlist.erase (it);
261 }
262 }
263 /*--- restore errno ---*/
265}
#define trace_with_mask(s, m)
trace_with_mask() is used to trace function call chain in C++ program.
Definition Logger.h:437
A wrapper class to provide AutoPtr with reference semantics.
Definition AutoPtr.h:32
EventHandler class.
SigHandlersList class.
static SigHandlersList * instance(int signum_)
Retrieve a pointer to the list of event handlers listening to signum_ signal delivery.
set< key_type, CompSHL >::iterator iterator
@ SIGHAND
Class SigHandler(s) messages
Definition LogMask.h:38

References ASSA::SigHandlersList::instance(), ASSA::SIGHAND, and trace_with_mask.

Referenced by sighandlers_dispatcher().

◆ install()

int SigHandlers::install ( int  signum_,
EventHandler new_hand_,
SigAction new_disp_ = 0,
EventHandler **  old_hand_ = 0,
SigAction old_disp_ = 0 
)
virtual

Register EventHandler with dispatching system.

Parameters
signum_(In ) Signal number.
new_hand_(In ) Pointer to new event handler to install.
new_disp_(In=0 ) New disposition to use to handle signal.
old_hand_(Out=0) Placeholder for old event handler.
old_disp_(Out=0) Placeholder for old disposition.
Returns
0 on success; -1 on error.

Reimplemented from ASSA::SigHandler.

Definition at line 35 of file SigHandlers.cpp.

41{
42 /*
43 Retrieve current signal disposition. If 3rd party handler has
44 already been istalled, make CFUNC_Handler out of it, and put it in
45 the list with id=0.
46
47 Add new_hand_ to the list. Has global sighandlers_dispatcher not
48 been installed yet, install it too.
49 */
50
51 trace_with_mask("SigHandlers::install()", SIGHAND);
52
53 if (!in_range(signum_) == -1) {
54 EL((ASSAERR,"in_range (%s) failed\n",signum_));
55 return -1;
56 }
57
60
62
63 /*--- Retrieve current signal disposition ---*/
64
66 cd.retrieve_action(signum_);
67
68 /*
69 Check whether 3rd party software has already installed
70 signal handler.
71 */
72 if ( cd.handler() != (C_SIG_HANDLER) sighandlers_dispatcher &&
73 cd.handler() != SIG_IGN &&
74 cd.handler() != SIG_DFL )
75 {
76 /*
77 Looks like some other code got ahead of me and installed C-function
78 signal handler. Make a note of it.
79
80 Create EventHandler to hold 3rd party handler. This handler will be
81 deleted only by SigHandlers::remove (NULL), when application demanded
82 to remove all of the handlers.
83 */
84 DL((SIGHAND,"Detected 3rd party \"C\" handler!\n"));
85
86 cfhp = new CFUNC_Handler (cd.handler ());
87 handlist->cfunc_handler (cfhp);
88
89 /*
90 Insert 3rd party handler in list of handlers
91 for this signal.
92 */
93 DL((SIGHAND,"Adding 3rd party \"C\" handler\n"));
94
95 if ( handlist->insert (cfhp) == false ) {
96 EL((ASSAERR, "Failed to insert "\
97 "c_func_handler for signum %d\n", signum_));
98 delete (cfhp);
99 handlist->cfunc_handler (0);
100 return -1;
101 }
102 DL((SIGHAND,"Set size: %d\n", handlist->size () ));
103 }
104 /*--- Add new_hand_ to the list of handlers for signum_. ---*/
105
106 DL((SIGHAND,"Adding EventHandler to the list\n"));
107
108 if (handlist->insert (new_hand_) == false) {
109 /*---
110 I failed to install new handler and might have already
111 added 3rd party CFUNC_Handler to the list without altering
112 disposition - if that's true, clean up the list.
113 ---*/
114 EL((ASSAERR,"failed to add new_hand_ to handlers list\n"));
115
116 if (handlist->seen_cfunc_handler () &&
117 handlist->size() == 1)
118 {
119 handlist->erase ();
120 handlist->cfunc_handler (0);
121 }
122 return -1;
123 }
124 DL((SIGHAND,"Set size: %d\n", handlist->size () ));
125
126 /*--- Has sighandlers_dispatcher been already installed? ---*/
127
128 if (cd.handler() == (C_SIG_HANDLER) sighandlers_dispatcher) {
129 return 0;
130 }
131 DL((SIGHAND,"Installing 'sighandlers_dispatcher'\n"));
132
133 /*
134 Installing new disposition; if user forgot to give me one
135 then default will be used.
136 */
138
139 if (new_disp_ == 0) {
140 new_disp_ = &sa;
141 }
142
144
145 if (new_disp_->register_action (signum_, old_disp_) == -1) {
146 /*---
147 I failed to install sighandlers_dispatcher. Up to this
148 point, if application had conventional C handler installed,
149 it still remains active. Handlers list built so far is
150 meaningless - get rid of it. ---*/
151
152 EL((ASSAERR,"register_action() error\n"));
153
154 if (handlist->seen_cfunc_handler ()) {
155 handlist->erase ();
156 handlist->cfunc_handler (0);
157 delete cfhp;
158 }
159 handlist->erase (new_hand_);
160 return -1;
161 }
162 return 0;
163}
#define EL(X)
A macro for writing error message to the Logger.
Definition Logger.h:285
#define DL(X)
A macro for writing debug message to the Logger.
Definition Logger.h:273
void(* C_SIG_HANDLER)(int)
Definition SigAction.h:28
CFUNC_Handler class.
int in_range(int signum_)
Check that signum_ is in valid range.
static void sighandlers_dispatcher(int signum_)
A wrapper around static SigHandlers::dispatch().
@ ASSAERR
ASSA and system errors
Definition LogMask.h:34

References ASSA::ASSAERR, DL, EL, ASSA::SigHandler::in_range(), ASSA::SigHandlersList::instance(), ASSA::SIGHAND, sighandlers_dispatcher(), and trace_with_mask.

Referenced by ASSA::GenServer::init().

◆ remove()

int SigHandlers::remove ( int  signum_,
EventHandler eh_,
SigAction new_disp_ = 0,
SigAction old_disp_ = 0 
)
virtual

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.

Parameters
signum_(In ) Signal number.
eh_(In ) Event handler to remove.
new_disp_(In=0 ) New disposition to use to handle signal.
old_disp_(Out=0) Placeholder for old disposition.
Returns
0 on success; -1 on error.

Reimplemented from ASSA::SigHandler.

Definition at line 166 of file SigHandlers.cpp.

170{
171 trace_with_mask("SigHandlers::remove()", SIGHAND);
172
173 if (in_range (signum_)) {
174 EL((ASSAERR, "singum_ %d is out of range\n", signum_));
175 return -1;
176 }
177
178 CFUNC_Handler* Cfhp = NULL; // pointer to C-function event handler
179 EventHandler* ehp = NULL; // pointer to current event handler
180
182
183 if (eh_ == NULL) {
184 DL((SIGHAND,"Erasing the entire set\n"));
185 /*--- Erase an entire list. ---*/
186 handlist.erase ();
187 DL((SIGHAND,"Set size: %d\n", handlist.size ()));
188 }
189 else {
190 /*
191 Note: I cannot do erasure in the same loop for following reason:
192
193 According to Stroustrup (Section 17.4.1.7):
194 "After erase(), the iterator cannot be used again because
195 the element to which it pointed is no longer there."
196
197 According to STL Tutorial and Ref. Guide:
198 "The erase function invalidates all iterators to all
199 positions past the point of erasure."
200
201 That's why here we first take care of id recycling and heap memory
202 deallocation, and only then clean() the map all at once.
203 */
205
206 if ((it = handlist.find (eh_)) != handlist.end ()) {
207 DL((SIGHAND,"Removing EventHandler\n"));
208 ehp = (*it);
209 handlist.erase (it);
210 }
211 DL((SIGHAND,"Set size: %d\n", handlist.size () ));
212 }
213 /*--- If set is not empty, we're done ---*/
214 if (handlist.size ()) return 0;
215
216 /* If map was emptied out, install new disposition
217 with the 3rd party "C" function handler, if we had it.
218 */
220 if (new_disp_ == 0) new_disp_ = &null_sa;
221
222 DL((SIGHAND,"Handlers List is empty\n"));
223
224 if (handlist.seen_cfunc_handler ()) {
225 /*--- Put 3rd party handler into disposition ---*/
226 DL((SIGHAND,"Reinstalling \"C\" handler\n"));
227 Cfhp = handlist.cfunc_handler (0);
228 new_disp_->handler (Cfhp->handler ());
229 delete Cfhp;
230 }
231 /*--- Install new disposition ---*/
232 return new_disp_->register_action (signum_, old_disp_);
233}

References ASSA::ASSAERR, DL, EL, ASSA::SigHandler::in_range(), ASSA::SigHandlersList::instance(), ASSA::SIGHAND, and trace_with_mask.

◆ sighandlers_dispatcher()

void SigHandlers::sighandlers_dispatcher ( int  signum_)
static

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.

Parameters
signum_Dispatch event handlers for this signal.

Definition at line 25 of file SigHandlers.cpp.

27{
28 trace_with_mask("SigHandlers::sighandlers_dispatch", SIGHAND);
29
30 DL((SIGHAND,"==> Received signal # %d\n", signum_));
32}
static void dispatch(int signum_)
The heart of SigHandlers class - this callback function is really registered with OS to catch all of ...

References dispatch(), DL, ASSA::SIGHAND, and trace_with_mask.

Referenced by install().


The documentation for this class was generated from the following files: