ANSI-ise a function declaration
[ghc-hetmet.git] / rts / posix / Signals.c
index 5f5f77f..fcfa1f1 100644 (file)
@@ -16,6 +16,8 @@
 #include "posix/Signals.h"
 #include "RtsUtils.h"
 #include "RtsFlags.h"
+#include "Prelude.h"
+#include "ThrIOManager.h"
 
 #ifdef alpha_HOST_ARCH
 # if defined(linux_HOST_OS)
@@ -39,7 +41,7 @@
  * to POSIX.1 to control whether or not to include SA_NOCLDSTOP when
  * installing a SIGCHLD handler. 
  */
-StgInt nocldstop = 0;
+HsInt nocldstop = 0;
 
 /* -----------------------------------------------------------------------------
  * The table of signal handlers
@@ -107,6 +109,9 @@ more_handlers(I_ sig)
 // Here's the pipe into which we will send our signals
 static int io_manager_pipe = -1;
 
+#define IO_MANAGER_WAKEUP 0xff
+#define IO_MANAGER_DIE    0xfe
+
 void
 setIOManagerPipe (int fd)
 {
@@ -115,6 +120,40 @@ setIOManagerPipe (int fd)
     io_manager_pipe = fd;
 }
 
+#if defined(THREADED_RTS)
+void
+ioManagerWakeup (void)
+{
+    // Wake up the IO Manager thread by sending a byte down its pipe
+    if (io_manager_pipe >= 0) {
+       StgWord8 byte = (StgWord8)IO_MANAGER_WAKEUP;
+       write(io_manager_pipe, &byte, 1);
+    }
+}
+
+void
+ioManagerDie (void)
+{
+    // Ask the IO Manager thread to exit
+    if (io_manager_pipe >= 0) {
+       StgWord8 byte = (StgWord8)IO_MANAGER_DIE;
+       write(io_manager_pipe, &byte, 1);
+    }
+}
+
+void
+ioManagerStart (void)
+{
+    // Make sure the IO manager thread is running
+    Capability *cap;
+    if (io_manager_pipe < 0) {
+       cap = rts_lock();
+       rts_evalIO(cap,&base_GHCziConc_ensureIOManagerIsRunning_closure,NULL);
+       rts_unlock(cap);
+    }
+}
+#endif
+
 #if !defined(THREADED_RTS)
 
 #define N_PENDING_HANDLERS 16
@@ -125,22 +164,6 @@ StgPtr *next_pending_handler = pending_handler_buf;
 #endif /* THREADED_RTS */
 
 /* -----------------------------------------------------------------------------
- * SIGCONT handler
- *
- * It seems that shells tend to put stdin back into blocking mode
- * following a suspend/resume of the process.  Here we arrange to put
- * it back into non-blocking mode.  We don't do anything to
- * stdout/stderr because these handles don't get put into non-blocking
- * mode at all - see the comments on stdout/stderr in PrelHandle.hsc.
- * -------------------------------------------------------------------------- */
-
-static void
-cont_handler(int sig STG_UNUSED)
-{
-    setNonBlockingFd(0);
-}
-
-/* -----------------------------------------------------------------------------
  * Low-level signal handler
  *
  * Places the requested handler on a stack of pending handlers to be
@@ -210,11 +233,6 @@ generic_handler(int sig)
     sigaddset(&signals, sig);
     sigprocmask(SIG_UNBLOCK, &signals, NULL);
 
-    // *always* do the SIGCONT handler, even if the user overrides it.
-    if (sig == SIGCONT) {
-       cont_handler(sig);
-    }
-
     context_switch = 1;
 }
 
@@ -374,19 +392,19 @@ startSignalHandlers(Capability *cap)
 
 #if !defined(THREADED_RTS)
 void
-markSignalHandlers (evac_fn evac)
+markSignalHandlers (evac_fn evac, void *user)
 {
     StgPtr *p;
 
     p = next_pending_handler;
     while (p != pending_handler_buf) {
        p--;
-       evac((StgClosure **)p);
+       evac(user, (StgClosure **)p);
     }
 }
 #else
 void
-markSignalHandlers (evac_fn evac STG_UNUSED)
+markSignalHandlers (evac_fn evac STG_UNUSED, void *user STG_UNUSED)
 {
 }
 #endif
@@ -411,24 +429,9 @@ stg_sig_install(StgInt sig STG_UNUSED,
  * We like to shutdown nicely after receiving a SIGINT, write out the
  * stats, write profiling info, close open files and flush buffers etc.
  * -------------------------------------------------------------------------- */
-#ifdef SMP
-pthread_t startup_guy;
-#endif
-
 static void
 shutdown_handler(int sig STG_UNUSED)
 {
-#ifdef SMP
-    // if I'm a worker thread, send this signal to the guy who
-    // originally called startupHaskell().  Since we're handling
-    // the signal, it won't be a "send to all threads" type of signal
-    // (according to the POSIX threads spec).
-    if (pthread_self() != startup_guy) {
-       pthread_kill(startup_guy, sig);
-       return;
-    }
-#endif
-
     // If we're already trying to interrupt the RTS, terminate with
     // extreme prejudice.  So the first ^C tries to exit the program
     // cleanly, and the second one just kills it.
@@ -455,34 +458,22 @@ shutdown_handler(int sig STG_UNUSED)
  * doesn't seem to do so.
  * -------------------------------------------------------------------------- */
 void
-initDefaultHandlers()
+initDefaultHandlers(void)
 {
     struct sigaction action,oact;
 
-#ifdef SMP
-    startup_guy = pthread_self();
-#endif
-
     // install the SIGINT handler
     action.sa_handler = shutdown_handler;
     sigemptyset(&action.sa_mask);
     action.sa_flags = 0;
     if (sigaction(SIGINT, &action, &oact) != 0) {
-       errorBelch("warning: failed to install SIGINT handler");
+       sysErrorBelch("warning: failed to install SIGINT handler");
     }
 
 #if defined(HAVE_SIGINTERRUPT)
     siginterrupt(SIGINT, 1);   // isn't this the default? --SDM
 #endif
 
-    // install the SIGCONT handler
-    action.sa_handler = cont_handler;
-    sigemptyset(&action.sa_mask);
-    action.sa_flags = 0;
-    if (sigaction(SIGCONT, &action, &oact) != 0) {
-       errorBelch("warning: failed to install SIGCONT handler");
-    }
-
     // install the SIGFPE handler
 
     // In addition to handling SIGINT, also handle SIGFPE by ignoring it.
@@ -498,7 +489,7 @@ initDefaultHandlers()
     sigemptyset(&action.sa_mask);
     action.sa_flags = 0;
     if (sigaction(SIGFPE, &action, &oact) != 0) {
-       errorBelch("warning: failed to install SIGFPE handler");
+       sysErrorBelch("warning: failed to install SIGFPE handler");
     }
 #endif
 
@@ -507,4 +498,11 @@ initDefaultHandlers()
 #endif
 }
 
+void
+freeSignalHandlers(void) {
+    if (signal_handlers != NULL) {
+        stgFree(signal_handlers);
+    }
+}
+
 #endif /* RTS_USER_SIGNALS */