1 #include "ace/Sig_Handler.h"
2 #include "ace/Sig_Adapter.h"
3 #include "ace/Signal.h"
4 #include "ace/Recursive_Thread_Mutex.h"
5 #include "ace/Managed_Object.h"
6 #include "ace/Containers.h"
7 #include "ace/Guard_T.h"
9 #if !defined (__ACE_INLINE__)
10 #include "ace/Sig_Handler.inl"
11 #endif /* __ACE_INLINE__ */
13 #if defined (ACE_HAS_SIG_C_FUNC)
16 ace_sig_handler_dispatch (int signum
, siginfo_t
*info
, ucontext_t
*context
)
18 ACE_TRACE ("ace_sig_handler_dispatch");
19 ACE_Sig_Handler::dispatch (signum
, info
, context
);
22 #define ace_signal_handler_dispatcher ACE_SignalHandler(ace_sig_handler_dispatch)
25 ace_sig_handlers_dispatch (int signum
, siginfo_t
*info
, ucontext_t
*context
)
27 ACE_TRACE ("ace_sig_handlers_dispatch");
28 ACE_Sig_Handlers::dispatch (signum
, info
, context
);
31 #define ace_signal_handlers_dispatcher ACE_SignalHandler(ace_sig_handlers_dispatch)
34 #define ace_signal_handler_dispatcher ACE_SignalHandler(ACE_Sig_Handler::dispatch)
36 #define ace_signal_handlers_dispatcher ACE_SignalHandler(ACE_Sig_Handlers::dispatch)
37 #endif /* ACE_HAS_SIG_C_FUNC */
39 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
41 /// Array of Event_Handlers that will handle the signals.
42 ACE_Event_Handler
*ACE_Sig_Handler::signal_handlers_
[ACE_NSIG
];
44 /// Remembers if a signal has occurred.
45 sig_atomic_t ACE_Sig_Handler::sig_pending_
= 0;
47 ACE_ALLOC_HOOK_DEFINE(ACE_Sig_Handler
)
49 ACE_Sig_Handler::~ACE_Sig_Handler (void)
51 for (int s
= 1; s
< ACE_NSIG
; ++s
)
52 if (ACE_Sig_Handler::signal_handlers_
[s
])
53 ACE_Sig_Handler::remove_handler_i (s
);
57 ACE_Sig_Handler::dump (void) const
59 #if defined (ACE_HAS_DUMP)
60 ACE_TRACE ("ACE_Sig_Handler::dump");
61 #endif /* ACE_HAS_DUMP */
65 ACE_Sig_Handler::sig_pending (void)
67 ACE_TRACE ("ACE_Sig_Handler::sig_pending");
68 ACE_MT (ACE_Recursive_Thread_Mutex
*lock
=
69 ACE_Managed_Object
<ACE_Recursive_Thread_Mutex
>::get_preallocated_object
70 (ACE_Object_Manager::ACE_SIG_HANDLER_LOCK
);
71 ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex
, m
, *lock
, 0));
72 return ACE_Sig_Handler::sig_pending_
!= 0;
76 ACE_Sig_Handler::sig_pending (int pending
)
78 ACE_TRACE ("ACE_Sig_Handler::sig_pending");
80 ACE_MT (ACE_Recursive_Thread_Mutex
*lock
=
81 ACE_Managed_Object
<ACE_Recursive_Thread_Mutex
>::get_preallocated_object
82 (ACE_Object_Manager::ACE_SIG_HANDLER_LOCK
);
83 ACE_GUARD (ACE_Recursive_Thread_Mutex
, m
, *lock
));
84 ACE_Sig_Handler::sig_pending_
= pending
;
88 ACE_Sig_Handler::handler (int signum
)
90 ACE_TRACE ("ACE_Sig_Handler::handler");
91 ACE_MT (ACE_Recursive_Thread_Mutex
*lock
=
92 ACE_Managed_Object
<ACE_Recursive_Thread_Mutex
>::get_preallocated_object
93 (ACE_Object_Manager::ACE_SIG_HANDLER_LOCK
);
94 ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex
, m
, *lock
, 0));
96 if (ACE_Sig_Handler::in_range (signum
))
97 return ACE_Sig_Handler::signal_handlers_
[signum
];
103 ACE_Sig_Handler::handler_i (int signum
,
104 ACE_Event_Handler
*new_sh
)
106 ACE_TRACE ("ACE_Sig_Handler::handler_i");
108 if (ACE_Sig_Handler::in_range (signum
))
110 ACE_Event_Handler
*sh
= ACE_Sig_Handler::signal_handlers_
[signum
];
112 ACE_Sig_Handler::signal_handlers_
[signum
] = new_sh
;
120 ACE_Sig_Handler::handler (int signum
,
121 ACE_Event_Handler
*new_sh
)
123 ACE_TRACE ("ACE_Sig_Handler::handler");
124 ACE_MT (ACE_Recursive_Thread_Mutex
*lock
=
125 ACE_Managed_Object
<ACE_Recursive_Thread_Mutex
>::get_preallocated_object
126 (ACE_Object_Manager::ACE_SIG_HANDLER_LOCK
);
127 ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex
, m
, *lock
, 0));
129 return ACE_Sig_Handler::handler_i (signum
, new_sh
);
132 /// Register an ACE_Event_Handler along with the corresponding SIGNUM.
133 /// This method does NOT acquire any locks, so it can be called from a
136 ACE_Sig_Handler::register_handler_i (int signum
,
137 ACE_Event_Handler
*new_sh
,
138 ACE_Sig_Action
*new_disp
,
139 ACE_Event_Handler
**old_sh
,
140 ACE_Sig_Action
*old_disp
)
142 ACE_TRACE ("ACE_Sig_Handler::register_handler_i");
144 if (ACE_Sig_Handler::in_range (signum
))
146 ACE_Sig_Action sa
; // Define a "null" action.
147 ACE_Event_Handler
*sh
= ACE_Sig_Handler::handler_i (signum
, new_sh
);
149 // Return a pointer to the old <ACE_Sig_Handler> if the user
154 // Make sure that <new_disp> points to a valid location if the
155 // user doesn't care...
159 new_disp
->handler (ace_signal_handler_dispatcher
);
160 #if !defined (ACE_HAS_LYNXOS4_SIGNALS)
161 new_disp
->flags (new_disp
->flags () | SA_SIGINFO
);
162 #endif /* ACE_HAS_LYNXOS4_SIGNALS */
163 return new_disp
->register_action (signum
, old_disp
);
169 /// Register an ACE_Event_Handler along with the corresponding SIGNUM.
170 /// This method acquires a lock, so it can't be called from a signal
171 /// handler, e.g., <dispatch>.
173 ACE_Sig_Handler::register_handler (int signum
,
174 ACE_Event_Handler
*new_sh
,
175 ACE_Sig_Action
*new_disp
,
176 ACE_Event_Handler
**old_sh
,
177 ACE_Sig_Action
*old_disp
)
179 ACE_TRACE ("ACE_Sig_Handler::register_handler");
180 ACE_MT (ACE_Recursive_Thread_Mutex
*lock
=
181 ACE_Managed_Object
<ACE_Recursive_Thread_Mutex
>::get_preallocated_object
182 (ACE_Object_Manager::ACE_SIG_HANDLER_LOCK
);
183 ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex
, m
, *lock
, -1));
185 return ACE_Sig_Handler::register_handler_i (signum
,
193 ACE_Sig_Handler::remove_handler_i (int signum
,
194 ACE_Sig_Action
*new_disp
,
195 ACE_Sig_Action
*old_disp
,
198 ACE_TRACE ("ACE_Sig_Handler::remove_handler_i");
200 ACE_Sig_Action
sa (SIG_DFL
, (sigset_t
*) 0); // Reset to default disposition.
205 ACE_Event_Handler
*eh
= ACE_Sig_Handler::signal_handlers_
[signum
];
206 ACE_Sig_Handler::signal_handlers_
[signum
] = 0;
208 // Allow the event handler to close down if necessary.
211 eh
->handle_close (ACE_INVALID_HANDLE
,
212 ACE_Event_Handler::SIGNAL_MASK
);
215 // Register either the new disposition or restore the default.
216 return new_disp
->register_action (signum
, old_disp
);
219 /// Remove an ACE_Event_Handler.
221 ACE_Sig_Handler::remove_handler (int signum
,
222 ACE_Sig_Action
*new_disp
,
223 ACE_Sig_Action
*old_disp
,
226 ACE_TRACE ("ACE_Sig_Handler::remove_handler");
227 ACE_MT (ACE_Recursive_Thread_Mutex
*lock
=
228 ACE_Managed_Object
<ACE_Recursive_Thread_Mutex
>::get_preallocated_object
229 (ACE_Object_Manager::ACE_SIG_HANDLER_LOCK
);
230 ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex
, m
, *lock
, -1));
232 if (ACE_Sig_Handler::in_range (signum
))
233 return ACE_Sig_Handler::remove_handler_i (signum
, new_disp
, old_disp
);
238 /// Master dispatcher function that gets called by a signal handler and
239 /// dispatches one handler...
241 ACE_Sig_Handler::dispatch (int signum
,
243 ucontext_t
*ucontext
)
245 ACE_TRACE ("ACE_Sig_Handler::dispatch");
247 // Save/restore errno.
248 ACE_Errno_Guard
error (errno
);
250 // We can't use the <sig_pending> call here because that acquires
251 // the lock, which is non-portable...
252 ACE_Sig_Handler::sig_pending_
= 1;
254 // Darn well better be in range since the OS dispatched this...
255 ACE_ASSERT (ACE_Sig_Handler::in_range (signum
));
257 ACE_Event_Handler
*eh
= ACE_Sig_Handler::signal_handlers_
[signum
];
261 if (eh
->handle_signal (signum
, siginfo
, ucontext
) == -1)
262 ACE_Sig_Handler::remove_handler_i (signum
);
263 #if defined (ACE_WIN32)
265 // Win32 is weird in the sense that it resets the signal
266 // disposition to SIG_DFL after a signal handler is
267 // dispatched. Therefore, to workaround this "feature" we
268 // must re-register the <ACE_Event_Handler> with <signum>
270 ACE_Sig_Handler::register_handler_i (signum
, eh
);
271 #endif /* ACE_WIN32*/
275 // ----------------------------------------
276 // The following classes are local to this file.
278 // There are bugs with HP/UX's C++ compiler that prevents this stuff
280 #define ACE_MAX_SIGNAL_HANDLERS ((size_t) 20)
282 /// Keeps track of the id that uniquely identifies each registered
283 /// signal handler. This id can be used to cancel a timer via the
284 /// <remove_handler> method.
285 int ACE_Sig_Handlers::sigkey_
= 0;
287 /// If this is true then a 3rd party library has registered a
289 bool ACE_Sig_Handlers::third_party_sig_handler_
= false;
291 // Make life easier by defining typedefs...
292 typedef ACE_Fixed_Set
<ACE_Event_Handler
*, ACE_MAX_SIGNAL_HANDLERS
> ACE_SIG_HANDLERS_SET
;
293 typedef ACE_Fixed_Set_Iterator
<ACE_Event_Handler
*, ACE_MAX_SIGNAL_HANDLERS
> ACE_SIG_HANDLERS_ITERATOR
;
295 class ACE_Sig_Handlers_Set
298 static ACE_SIG_HANDLERS_SET
*instance (int signum
);
301 static ACE_SIG_HANDLERS_SET
*sig_handlers_
[ACE_NSIG
];
305 ACE_SIG_HANDLERS_SET
*ACE_Sig_Handlers_Set::sig_handlers_
[ACE_NSIG
];
308 ACE_SIG_HANDLERS_SET
*
309 ACE_Sig_Handlers_Set::instance (int signum
)
311 if (signum
<= 0 || signum
>= ACE_NSIG
)
312 return 0; // This will cause problems...
313 else if (ACE_Sig_Handlers_Set::sig_handlers_
[signum
] == 0)
314 ACE_NEW_RETURN (ACE_Sig_Handlers_Set::sig_handlers_
[signum
],
315 ACE_SIG_HANDLERS_SET
,
317 return ACE_Sig_Handlers_Set::sig_handlers_
[signum
];
320 ACE_ALLOC_HOOK_DEFINE(ACE_Sig_Handlers
)
322 ACE_Sig_Handlers::ACE_Sig_Handlers (void)
327 ACE_Sig_Handlers::dump (void) const
329 #if defined (ACE_HAS_DUMP)
330 ACE_TRACE ("ACE_Sig_Handlers::dump");
331 #endif /* ACE_HAS_DUMP */
334 /// This is the method that does all the dirty work... The basic
335 /// structure of this method was devised by Detlef Becker.
337 ACE_Sig_Handlers::register_handler (int signum
,
338 ACE_Event_Handler
*new_sh
,
339 ACE_Sig_Action
*new_disp
,
340 ACE_Event_Handler
**,
341 ACE_Sig_Action
*old_disp
)
343 ACE_TRACE ("ACE_Sig_Handlers::register_handler");
344 ACE_MT (ACE_Recursive_Thread_Mutex
*lock
=
345 ACE_Managed_Object
<ACE_Recursive_Thread_Mutex
>::get_preallocated_object
346 (ACE_Object_Manager::ACE_SIG_HANDLER_LOCK
);
347 ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex
, m
, *lock
, -1));
349 if (ACE_Sig_Handler::in_range (signum
))
351 ACE_Sig_Adapter
*ace_sig_adapter
= 0; // Our signal handler.
352 ACE_Sig_Adapter
*extern_sh
= 0; // An external signal handler.
355 // Get current signal disposition.
356 sa
.retrieve_action (signum
);
358 // Check whether we are already in control of the signal
359 // handling disposition...
361 if (!(sa
.handler () == ace_signal_handlers_dispatcher
362 || sa
.handler () == ACE_SignalHandler (SIG_IGN
)
363 || sa
.handler () == ACE_SignalHandler (SIG_DFL
)))
365 // Drat, a 3rd party library has already installed a signal ;-(
367 // Upto here we never disabled RESTART_MODE. Thus,
368 // RESTART_MODE can only be changed by 3rd party libraries.
370 if (ACE_BIT_DISABLED (sa
.flags (), SA_RESTART
)
371 && ACE_Sig_Handlers::third_party_sig_handler_
)
372 // Toggling is disallowed since we might break 3rd party
376 // Note that we've seen a 3rd party handler...
377 ACE_Sig_Handlers::third_party_sig_handler_
= true;
379 // Create a new 3rd party disposition, remembering its
380 // preferred signal blocking etc...;
381 ACE_NEW_RETURN (extern_sh
,
383 ++ACE_Sig_Handlers::sigkey_
),
385 // Add the external signal handler to the set of handlers
387 if (ACE_Sig_Handlers_Set::instance (signum
)->insert (extern_sh
) == -1)
393 // Add our new handler at this point.
394 ACE_NEW_RETURN (ace_sig_adapter
,
395 ACE_Sig_Adapter (new_sh
,
396 ++ACE_Sig_Handlers::sigkey_
),
399 // Add the ACE signal handler to the set of handlers for this
400 // signal (make sure it goes before the external one if there is
402 int result
= ACE_Sig_Handlers_Set::instance (signum
)->insert (ace_sig_adapter
);
406 // We couldn't reinstall our handler, so let's pretend like
407 // none of this happened...
410 ACE_Sig_Handlers_Set::instance (signum
)->remove (extern_sh
);
413 delete ace_sig_adapter
;
416 // If ACE_Sig_Handlers::dispatch() was set we're done.
417 else if (sa
.handler () == ace_signal_handlers_dispatcher
)
418 return ace_sig_adapter
->sigkey ();
420 // Otherwise, we need to register our handler function so that
421 // all signals will be dispatched through ACE.
424 // Make sure that new_disp points to a valid location if the
425 // user doesn't care...
429 new_disp
->handler (ace_signal_handlers_dispatcher
);
431 // Default is to restart signal handlers.
432 new_disp
->flags (new_disp
->flags () | SA_RESTART
);
433 #if !defined (ACE_HAS_LYNXOS4_SIGNALS)
434 new_disp
->flags (new_disp
->flags () | SA_SIGINFO
);
435 #endif /* ACE_HAS_LYNXOS4_SIGNALS */
437 // Finally install (possibly reinstall) the ACE signal
438 // handler disposition with the SA_RESTART mode enabled.
439 if (new_disp
->register_action (signum
, old_disp
) == -1)
441 // Yikes, lots of roll back at this point...
442 ACE_Sig_Handlers_Set::instance (signum
)->remove (ace_sig_adapter
);
443 delete ace_sig_adapter
;
447 ACE_Sig_Handlers_Set::instance (signum
)->remove (extern_sh
);
452 else // Return the signal key so that programs can cancel this
453 // handler if they want!
454 return ace_sig_adapter
->sigkey ();
461 /// Remove the ACE_Event_Handler currently associated with @a signum.
462 /// Install the new disposition (if given) and return the previous
463 /// disposition (if desired by the caller). Returns 0 on success and
464 // -1 if @a signum is invalid.
466 ACE_Sig_Handlers::remove_handler (int signum
,
467 ACE_Sig_Action
*new_disp
,
468 ACE_Sig_Action
*old_disp
,
471 ACE_TRACE ("ACE_Sig_Handlers::remove_handler");
472 ACE_MT (ACE_Recursive_Thread_Mutex
*lock
=
473 ACE_Managed_Object
<ACE_Recursive_Thread_Mutex
>::get_preallocated_object
474 (ACE_Object_Manager::ACE_SIG_HANDLER_LOCK
);
475 ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex
, m
, *lock
, -1));
477 if (ACE_Sig_Handler::in_range (signum
))
479 ACE_SIG_HANDLERS_SET
*handler_set
=
480 ACE_Sig_Handlers_Set::instance (signum
);
482 ACE_SIG_HANDLERS_ITERATOR
handler_iterator (*handler_set
);
484 // Iterate through the set of handlers for this signal.
485 for (ACE_Event_Handler
**eh
;
486 handler_iterator
.next (eh
) != 0;
489 // Type-safe downcast would be nice here...
490 ACE_Sig_Adapter
*sh
= (ACE_Sig_Adapter
*) *eh
;
492 // Remove the handler if (1) its key matches the key we've
493 // been told to remove or (2) if we've been told to remove
494 // *all* handlers (i.e., <sigkey> == -1).
495 if (sh
->sigkey () == sigkey
|| sigkey
== -1)
497 handler_set
->remove (*eh
);
502 if (handler_set
->size () == 0)
504 // If there are no more handlers left for a signal then
505 // register the new disposition or restore the default
507 ACE_Sig_Action
sa (SIG_DFL
, (sigset_t
*) 0);
512 return new_disp
->register_action (signum
, old_disp
);
520 /// Master dispatcher function that gets called by a signal handler and
521 /// dispatches *all* the handlers...
523 ACE_Sig_Handlers::dispatch (int signum
,
525 ucontext_t
*ucontext
)
527 ACE_TRACE ("ACE_Sig_Handlers::dispatch");
528 // The following is #ifdef'd out because it's entirely non-portable
529 // to acquire a mutex in a signal handler...
531 ACE_MT (ACE_Recursive_Thread_Mutex
*lock
=
532 ACE_Managed_Object
<ACE_Recursive_Thread_Mutex
>::get_preallocated_object
533 (ACE_Object_Manager::ACE_SIG_HANDLER_LOCK
);
534 ACE_TSS_Guard
<ACE_Recursive_Thread_Mutex
> m (*lock
));
537 // Save/restore errno.
538 ACE_Errno_Guard
error (errno
);
540 ACE_Sig_Handler::sig_pending_
= 1;
542 // Darn well better be in range since the OS dispatched this...
543 ACE_ASSERT (ACE_Sig_Handler::in_range (signum
));
545 ACE_SIG_HANDLERS_SET
*handler_set
=
546 ACE_Sig_Handlers_Set::instance (signum
);
548 ACE_SIG_HANDLERS_ITERATOR
handler_iterator (*handler_set
);
550 for (ACE_Event_Handler
**eh
= 0;
551 handler_iterator
.next (eh
) != 0;
553 if ((*eh
)->handle_signal (signum
, siginfo
, ucontext
) == -1)
555 handler_set
->remove (*eh
);
560 /// Return the first item in the list of handlers. Note that this will
561 /// trivially provide the same behavior as the ACE_Sig_Handler
562 /// version if there is only 1 handler registered!
564 ACE_Sig_Handlers::handler (int signum
)
566 ACE_TRACE ("ACE_Sig_Handlers::handler");
567 ACE_SIG_HANDLERS_SET
*handler_set
=
568 ACE_Sig_Handlers_Set::instance (signum
);
569 ACE_SIG_HANDLERS_ITERATOR
handler_iterator (*handler_set
);
570 ACE_Event_Handler
**eh
= 0;
571 handler_iterator
.next (eh
);
575 /// The following is a strange bit of logic that tries to give the same
576 /// semantics as what happens in ACE_Sig_Handler when we replace the
577 /// current signal handler with a new one. Note that if there is only
578 /// one signal handler the behavior will be identical. If there is
579 /// more than one handler then things get weird...
581 ACE_Sig_Handlers::handler (int signum
, ACE_Event_Handler
*new_sh
)
583 ACE_TRACE ("ACE_Sig_Handlers::handler");
584 ACE_SIG_HANDLERS_SET
*handler_set
=
585 ACE_Sig_Handlers_Set::instance (signum
);
586 ACE_SIG_HANDLERS_ITERATOR
handler_iterator (*handler_set
);
587 ACE_Event_Handler
**eh
= 0;
589 // Find the first handler...
590 handler_iterator
.next (eh
);
592 // ... then remove it from the set ...
593 handler_set
->remove (*eh
);
595 // ... and then insert the new signal handler into the beginning of
596 // the set (note, this is a bit too tied up in the implementation of
597 // ACE_Unbounded_Set...).
598 ACE_Sig_Adapter
*temp
= 0;
600 ACE_NEW_RETURN (temp
,
601 ACE_Sig_Adapter (new_sh
,
602 ++ACE_Sig_Handlers::sigkey_
),
604 handler_set
->insert (temp
);
608 ACE_END_VERSIONED_NAMESPACE_DECL