summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--rts/Capability.c10
-rw-r--r--rts/IOManager.h5
2 files changed, 14 insertions, 1 deletions
diff --git a/rts/Capability.c b/rts/Capability.c
index 3ef604693b..c3ef3929d9 100644
--- a/rts/Capability.c
+++ b/rts/Capability.c
@@ -1221,7 +1221,15 @@ shutdownCapability (Capability *cap USED_IF_THREADS,
//
// To reproduce this deadlock: run ffi002(threaded1)
// repeatedly on a loaded machine.
- ioManagerDie();
+ //
+ // FIXME: stopIOManager is not a per-capability action. It shuts
+ // down the I/O subsystem for all capabilities, but here we call
+ // it once per cap, so this is accidentally quadratic, but mainly
+ // it is confusing. Replace this with a per-capability stop, and
+ // perhaps make it synchronous so it works the first time and we
+ // don't have to come back and try again here.
+ //
+ stopIOManager();
yieldThread();
continue;
}
diff --git a/rts/IOManager.h b/rts/IOManager.h
index 3a66760258..1059f4212e 100644
--- a/rts/IOManager.h
+++ b/rts/IOManager.h
@@ -39,6 +39,11 @@ void initIOManagerAfterFork(/* inout */ Capability **pcap);
/* Shutdown hooks: called from hs_exit_ before and after the scheduler exits.
+ *
+ * The stopIOManager is also called many times (once per-capability) within the
+ * scheduler shutdown (but only in threaded mode). This is despite the fact that
+ * stopIOManager shuts down the I/O manager for all capabilities.
+ * FIXME: this is accidentally quadratic and confusing.
*/
void stopIOManager(void);
void exitIOManager(bool wait_threads);