1 /* -----------------------------------------------------------------------------
3 * (c) The GHC Team, 1998-2005
5 * Signal processing / handling.
7 * ---------------------------------------------------------------------------*/
9 /* This is non-Posix-compliant.
10 #include "PosixSource.h"
15 #include "RtsSignals.h"
16 #include "posix/Signals.h"
21 #ifdef alpha_HOST_ARCH
22 # if defined(linux_HOST_OS)
25 # include <machine/fpu.h>
39 /* This curious flag is provided for the benefit of the Haskell binding
40 * to POSIX.1 to control whether or not to include SA_NOCLDSTOP when
41 * installing a SIGCHLD handler.
45 /* -----------------------------------------------------------------------------
46 * The table of signal handlers
47 * -------------------------------------------------------------------------- */
49 #if defined(RTS_USER_SIGNALS)
51 /* SUP: The type of handlers is a little bit, well, doubtful... */
52 StgInt *signal_handlers = NULL; /* Dynamically grown array of signal handlers */
53 static StgInt nHandlers = 0; /* Size of handlers array */
55 static nat n_haskell_handlers = 0;
57 /* -----------------------------------------------------------------------------
58 * Allocate/resize the table of signal handlers.
59 * -------------------------------------------------------------------------- */
69 if (signal_handlers == NULL)
70 signal_handlers = (StgInt *)stgMallocBytes((sig + 1) * sizeof(StgInt), "more_handlers");
72 signal_handlers = (StgInt *)stgReallocBytes(signal_handlers, (sig + 1) * sizeof(StgInt), "more_handlers");
74 for(i = nHandlers; i <= sig; i++)
75 // Fill in the new slots with default actions
76 signal_handlers[i] = STG_SIG_DFL;
81 /* -----------------------------------------------------------------------------
84 * The mechanism for starting handlers differs between the threaded
85 * (THREADED_RTS) and non-threaded versions of the RTS.
87 * When the RTS is single-threaded, we just write the pending signal
88 * handlers into a buffer, and start a thread for each one in the
91 * When THREADED_RTS, the problem is that signals might be
92 * delivered to multiple threads, so we would need to synchronise
93 * access to pending_handler_buf somehow. Using thread
94 * synchronisation from a signal handler isn't possible in general
95 * (some OSs support it, eg. MacOS X, but not all). So instead:
97 * - the signal handler writes the signal number into the pipe
98 * managed by the IO manager thread (see GHC.Conc).
99 * - the IO manager picks up the signal number and calls
100 * startSignalHandler() to start the thread.
102 * This also has the nice property that we don't need to arrange to
103 * wake up a worker task to start the signal handler: the IO manager
104 * wakes up when we write into the pipe.
106 * -------------------------------------------------------------------------- */
108 // Here's the pipe into which we will send our signals
109 static int io_manager_pipe = -1;
111 #define IO_MANAGER_WAKEUP 0xff
112 #define IO_MANAGER_DIE 0xfe
115 setIOManagerPipe (int fd)
117 // only called when THREADED_RTS, but unconditionally
118 // compiled here because GHC.Conc depends on it.
119 io_manager_pipe = fd;
122 #if defined(THREADED_RTS)
124 ioManagerWakeup (void)
126 // Wake up the IO Manager thread by sending a byte down its pipe
127 if (io_manager_pipe >= 0) {
128 StgWord8 byte = (StgWord8)IO_MANAGER_WAKEUP;
129 write(io_manager_pipe, &byte, 1);
136 // Ask the IO Manager thread to exit
137 if (io_manager_pipe >= 0) {
138 StgWord8 byte = (StgWord8)IO_MANAGER_DIE;
139 write(io_manager_pipe, &byte, 1);
144 ioManagerStart (void)
146 // Make sure the IO manager thread is running
148 if (io_manager_pipe < 0) {
150 rts_evalIO(cap,&GHCziConc_ensureIOManagerIsRunning_closure,NULL);
156 #if !defined(THREADED_RTS)
158 #define N_PENDING_HANDLERS 16
160 StgPtr pending_handler_buf[N_PENDING_HANDLERS];
161 StgPtr *next_pending_handler = pending_handler_buf;
163 #endif /* THREADED_RTS */
165 /* -----------------------------------------------------------------------------
168 * It seems that shells tend to put stdin back into blocking mode
169 * following a suspend/resume of the process. Here we arrange to put
170 * it back into non-blocking mode. We don't do anything to
171 * stdout/stderr because these handles don't get put into non-blocking
172 * mode at all - see the comments on stdout/stderr in PrelHandle.hsc.
173 * -------------------------------------------------------------------------- */
176 cont_handler(int sig STG_UNUSED)
181 /* -----------------------------------------------------------------------------
182 * Low-level signal handler
184 * Places the requested handler on a stack of pending handlers to be
185 * started up at the next context switch.
186 * -------------------------------------------------------------------------- */
189 generic_handler(int sig)
193 #if defined(THREADED_RTS)
195 if (io_manager_pipe != -1)
197 // Write the signal number into the pipe as a single byte. We
198 // hope that signals fit into a byte...
199 StgWord8 csig = (StgWord8)sig;
200 write(io_manager_pipe, &csig, 1);
202 // If the IO manager hasn't told us what the FD of the write end
203 // of its pipe is, there's not much we can do here, so just ignore
206 #else /* not THREADED_RTS */
208 /* Can't call allocate from here. Probably can't call malloc
209 either. However, we have to schedule a new thread somehow.
211 It's probably ok to request a context switch and allow the
212 scheduler to start the handler thread, but how do we
213 communicate this to the scheduler?
215 We need some kind of locking, but with low overhead (i.e. no
216 blocking signals every time around the scheduler).
218 Signal Handlers are atomic (i.e. they can't be interrupted), and
219 we can make use of this. We just need to make sure the
220 critical section of the scheduler can't be interrupted - the
221 only way to do this is to block signals. However, we can lower
222 the overhead by only blocking signals when there are any
223 handlers to run, i.e. the set of pending handlers is
227 /* We use a stack to store the pending signals. We can't
228 dynamically grow this since we can't allocate any memory from
229 within a signal handler.
231 Hence unfortunately we have to bomb out if the buffer
232 overflows. It might be acceptable to carry on in certain
233 circumstances, depending on the signal.
236 *next_pending_handler++ = deRefStablePtr((StgStablePtr)signal_handlers[sig]);
239 if (next_pending_handler == &pending_handler_buf[N_PENDING_HANDLERS]) {
240 errorBelch("too many pending signals");
241 stg_exit(EXIT_FAILURE);
244 #endif /* THREADED_RTS */
246 // re-establish the signal handler, and carry on
247 sigemptyset(&signals);
248 sigaddset(&signals, sig);
249 sigprocmask(SIG_UNBLOCK, &signals, NULL);
251 // *always* do the SIGCONT handler, even if the user overrides it.
252 if (sig == SIGCONT) {
259 /* -----------------------------------------------------------------------------
260 * Blocking/Unblocking of the user signals
261 * -------------------------------------------------------------------------- */
263 static sigset_t userSignals;
264 static sigset_t savedSignals;
267 initUserSignals(void)
269 sigemptyset(&userSignals);
273 blockUserSignals(void)
275 sigprocmask(SIG_BLOCK, &userSignals, &savedSignals);
279 unblockUserSignals(void)
281 sigprocmask(SIG_SETMASK, &savedSignals, NULL);
285 anyUserHandlers(void)
287 return n_haskell_handlers != 0;
290 #if !defined(THREADED_RTS)
292 awaitUserSignals(void)
294 while (!signals_pending() && sched_state == SCHED_RUNNING) {
300 /* -----------------------------------------------------------------------------
301 * Install a Haskell signal handler.
302 * -------------------------------------------------------------------------- */
305 stg_sig_install(int sig, int spi, StgStablePtr *handler, void *mask)
307 sigset_t signals, osignals;
308 struct sigaction action;
311 // Block the signal until we figure out what to do
312 // Count on this to fail if the signal number is invalid
313 if (sig < 0 || sigemptyset(&signals) ||
314 sigaddset(&signals, sig) || sigprocmask(SIG_BLOCK, &signals, &osignals)) {
320 previous_spi = signal_handlers[sig];
326 signal_handlers[sig] = STG_SIG_IGN;
327 sigdelset(&userSignals, sig);
328 action.sa_handler = SIG_IGN;
332 signal_handlers[sig] = STG_SIG_DFL;
333 sigdelset(&userSignals, sig);
334 action.sa_handler = SIG_DFL;
339 signal_handlers[sig] = (StgInt)*handler;
340 sigaddset(&userSignals, sig);
341 action.sa_handler = generic_handler;
342 if (spi == STG_SIG_RST) {
343 action.sa_flags = SA_RESETHAND;
345 n_haskell_handlers++;
349 barf("stg_sig_install: bad spi");
353 action.sa_mask = *(sigset_t *)mask;
355 sigemptyset(&action.sa_mask);
357 action.sa_flags |= sig == SIGCHLD && nocldstop ? SA_NOCLDSTOP : 0;
359 if (sigaction(sig, &action, NULL) ||
360 sigprocmask(SIG_SETMASK, &osignals, NULL))
362 // need to return an error code, so avoid a stable pointer leak
363 // by freeing the previous handler if there was one.
364 if (previous_spi >= 0) {
365 freeStablePtr(stgCast(StgStablePtr,signal_handlers[sig]));
366 n_haskell_handlers--;
371 if (previous_spi == STG_SIG_DFL || previous_spi == STG_SIG_IGN
372 || previous_spi == STG_SIG_ERR) {
375 *handler = (StgStablePtr)previous_spi;
380 /* -----------------------------------------------------------------------------
381 * Creating new threads for signal handlers.
382 * -------------------------------------------------------------------------- */
384 #if !defined(THREADED_RTS)
386 startSignalHandlers(Capability *cap)
390 while (next_pending_handler != pending_handler_buf) {
392 next_pending_handler--;
396 RtsFlags.GcFlags.initialStkSize,
397 (StgClosure *) *next_pending_handler));
400 unblockUserSignals();
404 /* ----------------------------------------------------------------------------
405 * Mark signal handlers during GC.
407 * We do this rather than trying to start all the signal handlers
408 * prior to GC, because that requires extra heap for the new threads.
409 * Signals must be blocked (see blockUserSignals() above) during GC to
410 * avoid race conditions.
411 * -------------------------------------------------------------------------- */
413 #if !defined(THREADED_RTS)
415 markSignalHandlers (evac_fn evac)
419 p = next_pending_handler;
420 while (p != pending_handler_buf) {
422 evac((StgClosure **)p);
427 markSignalHandlers (evac_fn evac STG_UNUSED)
432 #else /* !RTS_USER_SIGNALS */
434 stg_sig_install(StgInt sig STG_UNUSED,
435 StgInt spi STG_UNUSED,
436 StgStablePtr* handler STG_UNUSED,
437 void* mask STG_UNUSED)
439 //barf("User signals not supported");
445 #if defined(RTS_USER_SIGNALS)
446 /* -----------------------------------------------------------------------------
449 * We like to shutdown nicely after receiving a SIGINT, write out the
450 * stats, write profiling info, close open files and flush buffers etc.
451 * -------------------------------------------------------------------------- */
453 pthread_t startup_guy;
457 shutdown_handler(int sig STG_UNUSED)
460 // if I'm a worker thread, send this signal to the guy who
461 // originally called startupHaskell(). Since we're handling
462 // the signal, it won't be a "send to all threads" type of signal
463 // (according to the POSIX threads spec).
464 if (pthread_self() != startup_guy) {
465 pthread_kill(startup_guy, sig);
470 // If we're already trying to interrupt the RTS, terminate with
471 // extreme prejudice. So the first ^C tries to exit the program
472 // cleanly, and the second one just kills it.
473 if (sched_state >= SCHED_INTERRUPTING) {
474 stg_exit(EXIT_INTERRUPTED);
480 /* -----------------------------------------------------------------------------
481 * Install default signal handlers.
483 * The RTS installs a default signal handler for catching
484 * SIGINT, so that we can perform an orderly shutdown.
486 * Haskell code may install their own SIGINT handler, which is
487 * fine, provided they're so kind as to put back the old one
488 * when they de-install.
490 * In addition to handling SIGINT, the RTS also handles SIGFPE
491 * by ignoring it. Apparently IEEE requires floating-point
492 * exceptions to be ignored by default, but alpha-dec-osf3
493 * doesn't seem to do so.
494 * -------------------------------------------------------------------------- */
496 initDefaultHandlers()
498 struct sigaction action,oact;
501 startup_guy = pthread_self();
504 // install the SIGINT handler
505 action.sa_handler = shutdown_handler;
506 sigemptyset(&action.sa_mask);
508 if (sigaction(SIGINT, &action, &oact) != 0) {
509 errorBelch("warning: failed to install SIGINT handler");
512 #if defined(HAVE_SIGINTERRUPT)
513 siginterrupt(SIGINT, 1); // isn't this the default? --SDM
516 // install the SIGCONT handler
517 action.sa_handler = cont_handler;
518 sigemptyset(&action.sa_mask);
520 if (sigaction(SIGCONT, &action, &oact) != 0) {
521 errorBelch("warning: failed to install SIGCONT handler");
524 // install the SIGFPE handler
526 // In addition to handling SIGINT, also handle SIGFPE by ignoring it.
527 // Apparently IEEE requires floating-point exceptions to be ignored by
528 // default, but alpha-dec-osf3 doesn't seem to do so.
530 // Commented out by SDM 2/7/2002: this causes an infinite loop on
531 // some architectures when an integer division by zero occurs: we
532 // don't recover from the floating point exception, and the
533 // program just generates another one immediately.
535 action.sa_handler = SIG_IGN;
536 sigemptyset(&action.sa_mask);
538 if (sigaction(SIGFPE, &action, &oact) != 0) {
539 errorBelch("warning: failed to install SIGFPE handler");
543 #ifdef alpha_HOST_ARCH
544 ieee_set_fp_control(0);
548 #endif /* RTS_USER_SIGNALS */