summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDuncan Coutts <duncan@well-typed.com>2021-01-03 18:06:07 +0000
committerMarge Bot <ben+marge-bot@smart-cactus.org>2021-01-25 05:11:14 -0500
commitd345d3befe40cd265b9309f10c0aea057b2dd249 (patch)
treee1778144443ec2eace5189ba9a33c5c1779f5436
parent4ad726fc1a5d062e2df2910d7f39ab81428dddfc (diff)
downloadhaskell-d345d3befe40cd265b9309f10c0aea057b2dd249.tar.gz
Replace a direct call to ioManagerStartCap with a new hook
Replace a direct call to ioManagerStartCap in the forkProcess in Schedule.c with a new hook initIOManagerAfterFork in IOManager. This replaces a direct hook in the scheduler from the a single I/O manager impl (the threaded unix one) with a generic hook. Add some commentrary on opportunities for future rationalisation.
-rw-r--r--rts/IOManager.c28
-rw-r--r--rts/IOManager.h19
-rw-r--r--rts/Schedule.c4
3 files changed, 48 insertions, 3 deletions
diff --git a/rts/IOManager.c b/rts/IOManager.c
index eaa1fe8cb6..2e178435cb 100644
--- a/rts/IOManager.c
+++ b/rts/IOManager.c
@@ -20,6 +20,10 @@
#include "IOManager.h" // RTS internal
#include "Capability.h"
+#if !defined(mingw32_HOST_OS) && defined(THREADED_RTS)
+#include "posix/Signals.h"
+#endif
+
#if defined(mingw32_HOST_OS) && !defined(THREADED_RTS)
#include "win32/AsyncMIO.h"
#include "win32/AsyncWinIO.h"
@@ -55,6 +59,30 @@ initIOManager(void)
}
+/* Called from forkProcess in the child process on the surviving capability.
+ */
+void
+initIOManagerAfterFork(Capability **pcap USED_IF_THREADS_AND_NOT_MINGW32)
+{
+#if defined(THREADED_RTS) && !defined(mingw32_HOST_OS)
+ /* Posix implementation in posix/Signals.c
+ *
+ * No non-threaded impl because the non-threaded Posix select() I/O manager
+ * does not need any initialisation.
+ *
+ * No Windows impl since no forking.
+ *
+ * TODO: figure out if it is necessary for the threaded MIO case for the
+ * starting of the IO managager threads to be synchronous. It would be
+ * simpler if it could start them asynchronously and thus not have to
+ * have the pcap as an inout param, that could be modified. In practice it
+ * cannot be modified anyway since in the contexts where it is called
+ * (forkProcess), there is only a single cap available.
+ */
+ ioManagerStartCap(pcap);
+#endif
+}
+
/* Called in the RTS shutdown before the scheduler exits
*/
diff --git a/rts/IOManager.h b/rts/IOManager.h
index be9bc3ab1a..3a66760258 100644
--- a/rts/IOManager.h
+++ b/rts/IOManager.h
@@ -25,6 +25,18 @@
*/
void initIOManager(void);
+/* Init hook: called from forkProcess in the child process on the surviving
+ * capability.
+ *
+ * Note that this is synchronous and can run Haskell code, so can change the
+ * given cap.
+ */
+void initIOManagerAfterFork(/* inout */ Capability **pcap);
+
+/* TODO: rationalise initIOManager and initIOManagerAfterFork into a single
+ per-capability init function.
+ */
+
/* Shutdown hooks: called from hs_exit_ before and after the scheduler exits.
*/
@@ -52,4 +64,11 @@ void ioManagerStart (void);
#define USED_IF_NOT_THREADS_AND_MINGW32 STG_UNUSED
#endif
+#if defined(THREADED_RTS) && !defined(mingw32_HOST_OS)
+#define USED_IF_THREADS_AND_NOT_MINGW32
+#else
+#define USED_IF_THREADS_AND_NOT_MINGW32 STG_UNUSED
+#endif
+
+
#include "EndPrivate.h"
diff --git a/rts/Schedule.c b/rts/Schedule.c
index 810a70973b..0ee8f70cfe 100644
--- a/rts/Schedule.c
+++ b/rts/Schedule.c
@@ -2200,9 +2200,7 @@ forkProcess(HsStablePtr *entry
// like startup event, capabilities, process info etc
traceTaskCreate(task, cap);
-#if defined(THREADED_RTS)
- ioManagerStartCap(&cap);
-#endif
+ initIOManagerAfterFork(&cap);
// Install toplevel exception handlers, so interruption
// signal will be sent to the main thread.