fix up Win32 build
[ghc-hetmet.git] / ghc / rts / win32 / ConsoleHandler.c
index c68dc1d..413e13c 100644 (file)
@@ -10,6 +10,7 @@
 #include "RtsUtils.h"
 #include "RtsFlags.h"
 #include "AsyncIO.h"
+#include "RtsSignals.h"
 
 extern int stg_InstallConsoleEvent(int action, StgStablePtr *handler);
 
@@ -38,7 +39,7 @@ initUserSignals(void)
     if (hConsoleEvent == INVALID_HANDLE_VALUE) {
        hConsoleEvent = 
            CreateEvent ( NULL,  /* default security attributes */
-                         FALSE, /* auto-reset event */
+                         TRUE,  /* manual-reset event */
                          FALSE, /* initially non-signalled */
                          NULL); /* no name */
     }
@@ -69,7 +70,7 @@ static BOOL WINAPI shutdown_handler(DWORD dwCtrlType)
        // 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.
-       if (interrupted) {
+       if (sched_state >= SCHED_INTERRUPTING) {
            stg_exit(EXIT_INTERRUPTED);
        } else {
            interruptStgRts();
@@ -144,27 +145,33 @@ void awaitUserSignals(void)
  * Run the handlers associated with the stacked up console events. Console
  * event delivery is blocked for the duration of this call.
  */
-void startSignalHandlers(void)
+void startSignalHandlers(Capability *cap)
 {
     StgStablePtr handler;
 
     if (console_handler < 0) {
        return;
     }
+
     blockUserSignals();
+    ACQUIRE_LOCK(&sched_mutex);
     
     handler = deRefStablePtr((StgStablePtr)console_handler);
     while (stg_pending_events > 0) {
        stg_pending_events--;
-       scheduleThread(
-           createIOThread(RtsFlags.GcFlags.initialStkSize, 
-                          rts_apply((StgClosure *)handler,
-                                    rts_mkInt(stg_pending_buf[stg_pending_events]))));
+       scheduleThread(cap,
+           createIOThread(cap,
+                          RtsFlags.GcFlags.initialStkSize, 
+                          rts_apply(cap,
+                                    (StgClosure *)handler,
+                                    rts_mkInt(cap,
+                                              stg_pending_buf[stg_pending_events]))));
     }
+    
+    RELEASE_LOCK(&sched_mutex);
     unblockUserSignals();
 }
 
-
 /*
  * Function: markSignalHandlers()
  *
@@ -180,17 +187,6 @@ void markSignalHandlers (evac_fn evac)
 }
 
 
-/*
- * Function: handleSignalsInThisThread()
- * 
- * Have current (OS) thread assume responsibility of handling console events/signals.
- * Currently not used (by the console event handling code.)
- */
-void handleSignalsInThisThread(void)
-{
-    return;
-}
-
 /* 
  * Function: generic_handler()
  *
@@ -199,6 +195,8 @@ void handleSignalsInThisThread(void)
  */
 static BOOL WINAPI generic_handler(DWORD dwCtrlType)
 {
+    ACQUIRE_LOCK(&sched_mutex);
+
     /* Ultra-simple -- up the counter + signal a switch. */
     switch(dwCtrlType) {
     case CTRL_CLOSE_EVENT:
@@ -221,6 +219,8 @@ static BOOL WINAPI generic_handler(DWORD dwCtrlType)
        resetAbandonRequestWait();
        return TRUE;
     }
+
+    RELEASE_LOCK(&sched_mutex);
 }
 
 
@@ -291,7 +291,9 @@ rts_ConsoleHandlerDone(int ev)
     if ( (DWORD)ev == CTRL_BREAK_EVENT ||
         (DWORD)ev == CTRL_C_EVENT ) {
        /* only these two cause stdin system calls to abort.. */
-       SetEvent(hConsoleEvent); /* event is auto-reset */
+       SetEvent(hConsoleEvent); /* event is manual-reset */
+       Sleep(0); /* yield */
+       ResetEvent(hConsoleEvent); /* turn it back off again */
     }
 }