Commit 7434fb5b authored by Simon Marlow's avatar Simon Marlow

fix possible ^C problems

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.
parent 5a2769f0
......@@ -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
}
......
......@@ -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.
......
......@@ -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;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment