fix possible ^C problems
authorSimon Marlow <simonmar@microsoft.com>
Thu, 8 Jun 2006 14:44:57 +0000 (14:44 +0000)
committerSimon Marlow <simonmar@microsoft.com>
Thu, 8 Jun 2006 14:44:57 +0000 (14:44 +0000)
Calling prodAllCapabilities() from interruptStgRts() was wrong, for
the same reasons that we stopped doing it in handle_tick().  We now
use the same mechanism (send a byte down the pipe to the IO manager
thread), but abstract it in a wakeUpRts() function in the scheduler.

rts/Schedule.c
rts/Schedule.h
rts/Timer.c

index 270a7d8..d9adda4 100644 (file)
@@ -3446,8 +3446,37 @@ interruptStgRts(void)
 {
     sched_state = SCHED_INTERRUPTING;
     context_switch = 1;
+    wakeUpRts();
+}
+
+/* -----------------------------------------------------------------------------
+   Wake up the RTS
+   
+   This function causes at least one OS thread to wake up and run the
+   scheduler loop.  It is invoked when the RTS might be deadlocked, or
+   an external event has arrived that may need servicing (eg. a
+   keyboard interrupt).
+
+   In the single-threaded RTS we don't do anything here; we only have
+   one thread anyway, and the event that caused us to want to wake up
+   will have interrupted any blocking system call in progress anyway.
+   -------------------------------------------------------------------------- */
+
+void
+wakeUpRts(void)
+{
 #if defined(THREADED_RTS)
-    prodAllCapabilities();
+#if !defined(mingw32_HOST_OS)
+    // This forces the IO Manager thread to wakeup, which will
+    // in turn ensure that some OS thread wakes up and runs the
+    // scheduler loop, which will cause a GC and deadlock check.
+    ioManagerWakeup();
+#else
+    // On Windows this might be safe enough, because we aren't
+    // in a signal handler.  Later we should use the IO Manager,
+    // though.
+    prodOneCapability();
+#endif
 #endif
 }
 
index 3adb70f..e30e911 100644 (file)
@@ -43,6 +43,12 @@ void awakenBlockedQueue(StgBlockingQueueElement *q, StgClosure *node);
 void awakenBlockedQueue (Capability *cap, StgTSO *tso);
 #endif
 
+/* wakeUpRts()
+ * 
+ * Causes an OS thread to wake up and run the scheduler, if necessary.
+ */
+void wakeUpRts(void);
+
 /* unblockOne()
  *
  * Put the specified thread on the run queue of the given Capability.
index 4b13be4..b4f5f8f 100644 (file)
@@ -72,20 +72,8 @@ handle_tick(int unused STG_UNUSED)
          blackholes_need_checking = rtsTrue;
          /* hack: re-use the blackholes_need_checking flag */
          
-#if !defined(mingw32_HOST_OS)
-         // This forces the IO Manager thread to wakeup, which will
-         // in turn ensure that some OS thread wakes up and runs the
-         // scheduler loop, which will cause a GC and deadlock check.
-         ioManagerWakeup();
-#else
-         /* ToDo: this doesn't work.  Can't invoke
-          * pthread_cond_signal from a signal handler.
-          * Furthermore, we can't prod a capability that we
-          * might be holding.  What can we do?
-          */
-         prodOneCapability();
-#endif
       }
+      wakeUpRts();
       break;
   default:
       break;