1 /* -----------------------------------------------------------------------------
2 * $Id: Signals.c,v 1.41 2004/08/13 13:10:44 simonmar Exp $
4 * (c) The GHC Team, 1998-1999
6 * Signal processing / handling.
8 * ---------------------------------------------------------------------------*/
10 /* This is non-Posix-compliant.
11 #include "PosixSource.h"
20 #ifdef alpha_TARGET_ARCH
21 # if defined(linux_TARGET_OS)
24 # include <machine/fpu.h>
38 /* This curious flag is provided for the benefit of the Haskell binding
39 * to POSIX.1 to control whether or not to include SA_NOCLDSTOP when
40 * installing a SIGCHLD handler.
45 #if defined(RTS_USER_SIGNALS)
47 /* SUP: The type of handlers is a little bit, well, doubtful... */
48 static StgInt *handlers = NULL; /* Dynamically grown array of signal handlers */
49 static StgInt nHandlers = 0; /* Size of handlers array */
51 static nat n_haskell_handlers = 0;
53 #define N_PENDING_HANDLERS 16
55 StgPtr pending_handler_buf[N_PENDING_HANDLERS];
56 StgPtr *next_pending_handler = pending_handler_buf;
58 #ifdef RTS_SUPPORTS_THREADS
59 pthread_t signalHandlingThread;
62 // Handle all signals in the current thread.
63 // Called from Capability.c whenever the main capability is granted to a thread
64 // and in installDefaultHandlers
66 handleSignalsInThisThread()
68 #ifdef RTS_SUPPORTS_THREADS
69 signalHandlingThread = pthread_self();
74 /* -----------------------------------------------------------------------------
75 * Allocate/resize the table of signal handlers.
76 * -------------------------------------------------------------------------- */
87 handlers = (StgInt *)stgMallocBytes((sig + 1) * sizeof(StgInt), "more_handlers");
89 handlers = (StgInt *)stgReallocBytes(handlers, (sig + 1) * sizeof(StgInt), "more_handlers");
91 for(i = nHandlers; i <= sig; i++)
92 // Fill in the new slots with default actions
93 handlers[i] = STG_SIG_DFL;
98 /* -----------------------------------------------------------------------------
101 * It seems that shells tend to put stdin back into blocking mode
102 * following a suspend/resume of the process. Here we arrange to put
103 * it back into non-blocking mode. We don't do anything to
104 * stdout/stderr because these handles don't get put into non-blocking
105 * mode at all - see the comments on stdout/stderr in PrelHandle.hsc.
106 * -------------------------------------------------------------------------- */
109 cont_handler(int sig STG_UNUSED)
114 /* -----------------------------------------------------------------------------
115 * Low-level signal handler
117 * Places the requested handler on a stack of pending handlers to be
118 * started up at the next context switch.
119 * -------------------------------------------------------------------------- */
122 generic_handler(int sig)
126 #if defined(THREADED_RTS)
127 // Make the thread that currently holds the main capability
128 // handle the signal.
129 // This makes sure that awaitEvent() is interrupted
130 // and it (hopefully) prevents race conditions
131 // (signal handlers are not atomic with respect to other threads)
133 if(pthread_self() != signalHandlingThread) {
134 pthread_kill(signalHandlingThread, sig);
139 /* Can't call allocate from here. Probably can't call malloc
140 either. However, we have to schedule a new thread somehow.
142 It's probably ok to request a context switch and allow the
143 scheduler to start the handler thread, but how do we
144 communicate this to the scheduler?
146 We need some kind of locking, but with low overhead (i.e. no
147 blocking signals every time around the scheduler).
149 Signal Handlers are atomic (i.e. they can't be interrupted), and
150 we can make use of this. We just need to make sure the
151 critical section of the scheduler can't be interrupted - the
152 only way to do this is to block signals. However, we can lower
153 the overhead by only blocking signals when there are any
154 handlers to run, i.e. the set of pending handlers is
158 /* We use a stack to store the pending signals. We can't
159 dynamically grow this since we can't allocate any memory from
160 within a signal handler.
162 Hence unfortunately we have to bomb out if the buffer
163 overflows. It might be acceptable to carry on in certain
164 circumstances, depending on the signal.
167 *next_pending_handler++ = deRefStablePtr((StgStablePtr)handlers[sig]);
170 if (next_pending_handler == &pending_handler_buf[N_PENDING_HANDLERS]) {
171 prog_belch("too many pending signals");
172 stg_exit(EXIT_FAILURE);
175 // re-establish the signal handler, and carry on
176 sigemptyset(&signals);
177 sigaddset(&signals, sig);
178 sigprocmask(SIG_UNBLOCK, &signals, NULL);
180 // *always* do the SIGCONT handler, even if the user overrides it.
181 if (sig == SIGCONT) {
188 /* -----------------------------------------------------------------------------
189 * Blocking/Unblocking of the user signals
190 * -------------------------------------------------------------------------- */
192 static sigset_t userSignals;
193 static sigset_t savedSignals;
196 initUserSignals(void)
198 sigemptyset(&userSignals);
202 blockUserSignals(void)
204 sigprocmask(SIG_BLOCK, &userSignals, &savedSignals);
208 unblockUserSignals(void)
210 sigprocmask(SIG_SETMASK, &savedSignals, NULL);
214 anyUserHandlers(void)
216 return n_haskell_handlers != 0;
220 awaitUserSignals(void)
222 while (!signals_pending() && !interrupted) {
227 /* -----------------------------------------------------------------------------
228 * Install a Haskell signal handler.
229 * -------------------------------------------------------------------------- */
232 stg_sig_install(int sig, int spi, StgStablePtr *handler, void *mask)
234 sigset_t signals, osignals;
235 struct sigaction action;
238 // Block the signal until we figure out what to do
239 // Count on this to fail if the signal number is invalid
240 if (sig < 0 || sigemptyset(&signals) ||
241 sigaddset(&signals, sig) || sigprocmask(SIG_BLOCK, &signals, &osignals)) {
247 previous_spi = handlers[sig];
253 handlers[sig] = STG_SIG_IGN;
254 sigdelset(&userSignals, sig);
255 action.sa_handler = SIG_IGN;
259 handlers[sig] = STG_SIG_DFL;
260 sigdelset(&userSignals, sig);
261 action.sa_handler = SIG_DFL;
266 handlers[sig] = (StgInt)*handler;
267 sigaddset(&userSignals, sig);
268 action.sa_handler = generic_handler;
269 if (spi == STG_SIG_RST) {
270 action.sa_flags = SA_RESETHAND;
272 n_haskell_handlers++;
276 barf("stg_sig_install: bad spi");
280 action.sa_mask = *(sigset_t *)mask;
282 sigemptyset(&action.sa_mask);
284 action.sa_flags |= sig == SIGCHLD && nocldstop ? SA_NOCLDSTOP : 0;
286 if (sigaction(sig, &action, NULL) ||
287 sigprocmask(SIG_SETMASK, &osignals, NULL))
289 // need to return an error code, so avoid a stable pointer leak
290 // by freeing the previous handler if there was one.
291 if (previous_spi >= 0) {
292 freeStablePtr(stgCast(StgStablePtr,handlers[sig]));
293 n_haskell_handlers--;
298 if (previous_spi == STG_SIG_DFL || previous_spi == STG_SIG_IGN
299 || previous_spi == STG_SIG_ERR) {
302 *handler = (StgStablePtr)previous_spi;
307 /* -----------------------------------------------------------------------------
308 * Creating new threads for the pending signal handlers.
309 * -------------------------------------------------------------------------- */
311 startSignalHandlers(void)
315 while (next_pending_handler != pending_handler_buf) {
317 next_pending_handler--;
320 createIOThread(RtsFlags.GcFlags.initialStkSize,
321 (StgClosure *) *next_pending_handler));
324 unblockUserSignals();
327 /* ----------------------------------------------------------------------------
328 * Mark signal handlers during GC.
330 * We do this rather than trying to start all the signal handlers
331 * prior to GC, because that requires extra heap for the new threads.
332 * Signals must be blocked (see blockUserSignals() above) during GC to
333 * avoid race conditions.
334 * -------------------------------------------------------------------------- */
337 markSignalHandlers (evac_fn evac)
341 p = next_pending_handler;
342 while (p != pending_handler_buf) {
344 evac((StgClosure **)p);
348 #else /* !RTS_USER_SIGNALS */
350 stg_sig_install(StgInt sig STG_UNUSED,
351 StgInt spi STG_UNUSED,
352 StgStablePtr* handler STG_UNUSED,
353 void* mask STG_UNUSED)
355 //barf("User signals not supported");
361 #if defined(RTS_USER_SIGNALS)
362 /* -----------------------------------------------------------------------------
365 * We like to shutdown nicely after receiving a SIGINT, write out the
366 * stats, write profiling info, close open files and flush buffers etc.
367 * -------------------------------------------------------------------------- */
369 pthread_t startup_guy;
373 shutdown_handler(int sig STG_UNUSED)
376 // if I'm a worker thread, send this signal to the guy who
377 // originally called startupHaskell(). Since we're handling
378 // the signal, it won't be a "send to all threads" type of signal
379 // (according to the POSIX threads spec).
380 if (pthread_self() != startup_guy) {
381 pthread_kill(startup_guy, sig);
384 // ToDo: The code for the threaded RTS below does something very
385 // similar. Maybe the SMP special case is not needed
386 // -- Wolfgang Thaller
387 #elif defined(THREADED_RTS)
388 // Make the thread that currently holds the main capability
389 // handle the signal.
390 // This makes sure that awaitEvent() is interrupted
391 if(pthread_self() != signalHandlingThread) {
392 pthread_kill(signalHandlingThread, sig);
397 // If we're already trying to interrupt the RTS, terminate with
398 // extreme prejudice. So the first ^C tries to exit the program
399 // cleanly, and the second one just kills it.
401 stg_exit(EXIT_INTERRUPTED);
407 /* -----------------------------------------------------------------------------
408 * Install default signal handlers.
410 * The RTS installs a default signal handler for catching
411 * SIGINT, so that we can perform an orderly shutdown.
413 * Haskell code may install their own SIGINT handler, which is
414 * fine, provided they're so kind as to put back the old one
415 * when they de-install.
417 * In addition to handling SIGINT, the RTS also handles SIGFPE
418 * by ignoring it. Apparently IEEE requires floating-point
419 * exceptions to be ignored by default, but alpha-dec-osf3
420 * doesn't seem to do so.
421 * -------------------------------------------------------------------------- */
423 initDefaultHandlers()
425 struct sigaction action,oact;
428 startup_guy = pthread_self();
430 #ifdef RTS_SUPPORTS_THREADS
431 handleSignalsInThisThread();
434 // install the SIGINT handler
435 action.sa_handler = shutdown_handler;
436 sigemptyset(&action.sa_mask);
438 if (sigaction(SIGINT, &action, &oact) != 0) {
439 prog_belch("warning: failed to install SIGINT handler");
442 #if defined(HAVE_SIGINTERRUPT)
443 siginterrupt(SIGINT, 1); // isn't this the default? --SDM
446 // install the SIGCONT handler
447 action.sa_handler = cont_handler;
448 sigemptyset(&action.sa_mask);
450 if (sigaction(SIGCONT, &action, &oact) != 0) {
451 prog_belch("warning: failed to install SIGCONT handler");
454 // install the SIGFPE handler
456 // In addition to handling SIGINT, also handle SIGFPE by ignoring it.
457 // Apparently IEEE requires floating-point exceptions to be ignored by
458 // default, but alpha-dec-osf3 doesn't seem to do so.
460 // Commented out by SDM 2/7/2002: this causes an infinite loop on
461 // some architectures when an integer division by zero occurs: we
462 // don't recover from the floating point exception, and the
463 // program just generates another one immediately.
465 action.sa_handler = SIG_IGN;
466 sigemptyset(&action.sa_mask);
468 if (sigaction(SIGFPE, &action, &oact) != 0) {
469 prog_belch("warning: failed to install SIGFPE handler");
473 #ifdef alpha_TARGET_ARCH
474 ieee_set_fp_control(0);
478 #endif /* RTS_USER_SIGNALS */