[project @ 2005-11-03 15:15:14 by simonmar]
authorsimonmar <unknown>
Thu, 3 Nov 2005 15:15:14 +0000 (15:15 +0000)
committersimonmar <unknown>
Thu, 3 Nov 2005 15:15:14 +0000 (15:15 +0000)
Fixes for console event handling on Win32 in the threaded/SMP runtime.
(it now builds, but is untested).

ghc/rts/RtsSignals.h
ghc/rts/Schedule.c
ghc/rts/posix/Signals.c
ghc/rts/win32/AwaitEvent.c
ghc/rts/win32/ConsoleHandler.c
ghc/rts/win32/ConsoleHandler.h

index 439ba0b..5f7c99b 100644 (file)
@@ -22,7 +22,6 @@
 #else /* PAR */
 
 #define signals_pending() (rtsFalse)
-#define handleSignalsInThisThread() /* nothing */
 
 #endif /* PAR */
 
index d8cee87..6528fdd 100644 (file)
@@ -47,6 +47,9 @@
 #include "Capability.h"
 #include "Task.h"
 #include "AwaitEvent.h"
+#if defined(mingw32_HOST_OS)
+#include "win32/IOManager.h"
+#endif
 
 #ifdef HAVE_SYS_TYPES_H
 #include <sys/types.h>
@@ -213,7 +216,7 @@ static void schedulePreLoop (void);
 #if defined(SMP)
 static void schedulePushWork(Capability *cap, Task *task);
 #endif
-static void scheduleStartSignalHandlers (void);
+static void scheduleStartSignalHandlers (Capability *cap);
 static void scheduleCheckBlockedThreads (Capability *cap);
 static void scheduleCheckBlackHoles (Capability *cap);
 static void scheduleDetectDeadlock (Capability *cap, Task *task);
@@ -447,7 +450,7 @@ schedule (Capability *initialCapability, Task *task)
     }
 #endif // SMP
 
-    scheduleStartSignalHandlers();
+    scheduleStartSignalHandlers(cap);
 
     // Only check the black holes here if we've nothing else to do.
     // During normal execution, the black hole list only gets checked
@@ -807,11 +810,11 @@ schedulePushWork(Capability *cap USED_WHEN_SMP,
  * ------------------------------------------------------------------------- */
 
 static void
-scheduleStartSignalHandlers(void)
+scheduleStartSignalHandlers(Capability *cap)
 {
-#if defined(RTS_USER_SIGNALS) && !defined(THREADED_RTS)
+#if defined(RTS_USER_SIGNALS) && (!defined(THREADED_RTS) || defined(mingw32_HOST_OS))
     if (signals_pending()) { // safe outside the lock
-       startSignalHandlers();
+       startSignalHandlers(cap);
     }
 #endif
 }
@@ -897,7 +900,7 @@ scheduleDetectDeadlock (Capability *cap, Task *task)
        
        if ( !emptyRunQueue(cap) ) return;
 
-#if defined(RTS_USER_SIGNALS) && !defined(THREADED_RTS)
+#if defined(RTS_USER_SIGNALS) && (!defined(THREADED_RTS) || defined(mingw32_HOST_OS))
        /* If we have user-installed signal handlers, then wait
         * for signals to arrive rather then bombing out with a
         * deadlock.
@@ -909,7 +912,7 @@ scheduleDetectDeadlock (Capability *cap, Task *task)
            awaitUserSignals();
 
            if (signals_pending()) {
-               startSignalHandlers();
+               startSignalHandlers(cap);
            }
 
            // either we have threads to run, or we were interrupted:
index 0bceeb4..036411f 100644 (file)
@@ -349,8 +349,6 @@ startSignalHandlers(void)
 {
   blockUserSignals();
   
-  ASSERT_LOCK_HELD(&sched_mutex);
-
   while (next_pending_handler != pending_handler_buf) {
 
     next_pending_handler--;
index d9e2cbc..d1dca63 100644 (file)
@@ -1,3 +1,4 @@
+#if !defined(THREADED_RTS) /* to the end */
 /*
  * Wait/check for external events. Periodically, the
  * Scheduler checks for the completion of external operations,
@@ -47,3 +48,4 @@ awaitEvent(rtsBool wait)
           && emptyRunQueue(&MainCapability)
       );
 }
+#endif
index e17b529..0a45e12 100644 (file)
@@ -145,30 +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(&MainCapability,
-           createIOThread(&MainCapability,
+       scheduleThread(cap,
+           createIOThread(cap,
                           RtsFlags.GcFlags.initialStkSize, 
-                          rts_apply(&MainCapability,
+                          rts_apply(cap,
                                     (StgClosure *)handler,
-                                    rts_mkInt(&MainCapability,
+                                    rts_mkInt(cap,
                                               stg_pending_buf[stg_pending_events]))));
     }
+    
+    RELEASE_LOCK(&sched_mutex);
     unblockUserSignals();
 }
 
-
 /*
  * Function: markSignalHandlers()
  *
@@ -184,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()
  *
@@ -203,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:
@@ -225,6 +219,8 @@ static BOOL WINAPI generic_handler(DWORD dwCtrlType)
        resetAbandonRequestWait();
        return TRUE;
     }
+
+    RELEASE_LOCK(&sched_mutex);
 }
 
 
index 9c76c47..b09adf7 100644 (file)
@@ -42,7 +42,7 @@ extern StgInt stg_pending_events;
  * Run the handlers associated with the queued up console events. Console
  * event delivery is blocked for the duration of this call.
  */
-extern void startSignalHandlers(void);
+extern void startSignalHandlers(Capability *cap);
 
 /*
  * Function: handleSignalsInThisThread()