summaryrefslogtreecommitdiff
path: root/rts/Capability.c
diff options
context:
space:
mode:
authorAndreas Voellmy <andreas.voellmy@gmail.com>2014-08-19 08:02:18 -0500
committerAustin Seipp <austin@well-typed.com>2014-08-19 08:03:34 -0500
commitf9f89b7884ccc8ee5047cf4fffdf2b36df6832df (patch)
tree2871a2b4bca35ed8f2cecdb71d72ce66885a2c54 /rts/Capability.c
parent51a0b60038fb1dddbb9793c0c069de6125f84bf1 (diff)
downloadhaskell-f9f89b7884ccc8ee5047cf4fffdf2b36df6832df.tar.gz
rts/base: Fix #9423
Summary: Fix #9423. The problem in #9423 is caused when code invoked by `hs_exit()` waits on all foreign calls to return, but some IO managers are in `safe` foreign calls and do not return. The previous design signaled to the timer manager (via its control pipe) that it should "die" and when the timer manager returned to Haskell-land, the Haskell code in timer manager then signalled to the IO manager threads that they should return from foreign calls and `die`. Unfortunately, in the shutdown sequence the timer manager is unable to return to Haskell-land fast enough and so the code that signals to the IO manager threads (via their control pipes) is never executed and the IO manager threads remain out in the foreign calls. This patch solves this problem by having the RTS signal to all the IO manager threads (via their control pipes; and in addition to signalling to the timer manager thread) that they should shutdown (in `ioManagerDie()` in `rts/Signals.c`. To do this, we arrange for each IO manager thread to register its control pipe with the RTS (in `GHC.Thread.startIOManagerThread`). In addition, `GHC.Thread.startTimerManagerThread` registers its control pipe. These are registered via C functions `setTimerManagerControlFd` (in `rts/Signals.c`) and `setIOManagerControlFd` (in `rts/Capability.c`). The IO manager control pipe file descriptors are stored in a new field of the `Capability_ struct`. Test Plan: See the notes on #9423 to recreate the problem and to verify that it no longer occurs with the fix. Auditors: simonmar Reviewers: simonmar, edsko, ezyang, austin Reviewed By: austin Subscribers: phaskell, simonmar, ezyang, carter, relrod Differential Revision: https://phabricator.haskell.org/D129 GHC Trac Issues: #9423, #9284
Diffstat (limited to 'rts/Capability.c')
-rw-r--r--rts/Capability.c11
1 files changed, 11 insertions, 0 deletions
diff --git a/rts/Capability.c b/rts/Capability.c
index 29c5270416..4543ec7d1a 100644
--- a/rts/Capability.c
+++ b/rts/Capability.c
@@ -255,6 +255,7 @@ initCapability( Capability *cap, nat i )
cap->spark_stats.converted = 0;
cap->spark_stats.gcd = 0;
cap->spark_stats.fizzled = 0;
+ cap->io_manager_control_wr_fd = -1;
#endif
cap->total_allocated = 0;
@@ -1076,6 +1077,16 @@ rtsBool checkSparkCountInvariant (void)
}
#endif
+void setIOManagerControlFd(nat cap_no USED_IF_THREADS, int fd USED_IF_THREADS) {
+#if defined(THREADED_RTS)
+ if (cap_no < n_capabilities) {
+ capabilities[cap_no]->io_manager_control_wr_fd = fd;
+ } else {
+ errorBelch("warning: setIOManagerControlFd called with illegal capability number.");
+ }
+#endif
+}
+
// Local Variables:
// mode: C
// fill-column: 80