#define RTS_LIBGCC_SYMBOLS
#endif
+/* NOTE [io-manager-ghci]
+
+ When GHCi loads the base package, it gets another copy of the CAFs
+ in GHC.Conc that record the IO manager's ThreadId, and the blocking
+ queues, so we get another IO manager. This is bad enough, but what
+ is worse is that GHCi by default reverts all CAFs on every :load,
+ so we'll get *another* IO manager thread (and an associated pipe)
+ every time the user does :load. Miraculously, this actually
+ manages to just about work in GHC 6.10 and earlier, but broke when
+ I tried to fix #1185 (restarting the IO manager after a fork()).
+
+ To work around it and ensure that we only have a single IO manager,
+ we map the CAFs in the dynamically-loaded GHC.Conc to the
+ statically-linked GHC.Conc. This is an ugly hack, but it's the
+ least ugly hack that I could think of (SDM 3/11/2009)
+*/
+
+#define RTS_GHC_CONC_SYMBOLS \
+ SymI_NeedsProto(base_GHCziConc_pendingDelays_closure) \
+ SymI_NeedsProto(base_GHCziConc_pendingEvents_closure) \
+ SymI_NeedsProto(base_GHCziConc_ioManagerThread_closure)
+
+#ifdef mingw32_HOST_OS
+#define RTS_GHC_CONC_OS_SYMBOLS /* empty */
+#else
+#define RTS_GHC_CONC_OS_SYMBOLS \
+ SymI_NeedsProto(base_GHCziConc_prodding_closure) \
+ SymI_NeedsProto(base_GHCziConc_sync_closure) \
+ SymI_NeedsProto(base_GHCziConc_stick_closure)
+#endif
+
#if defined(darwin_HOST_OS) && defined(powerpc_HOST_ARCH)
// Symbols that don't have a leading underscore
// on Mac OS X. They have to receive special treatment,
RTS_DARWIN_ONLY_SYMBOLS
RTS_LIBGCC_SYMBOLS
RTS_LIBFFI_SYMBOLS
+RTS_GHC_CONC_SYMBOLS
+RTS_GHC_CONC_OS_SYMBOLS
#undef SymI_NeedsProto
#undef SymI_HasProto
#undef SymI_HasProto_redirect
RTS_DARWIN_ONLY_SYMBOLS
RTS_LIBGCC_SYMBOLS
RTS_LIBFFI_SYMBOLS
+ RTS_GHC_CONC_SYMBOLS
+ RTS_GHC_CONC_OS_SYMBOLS
#if defined(darwin_HOST_OS) && defined(i386_HOST_ARCH)
// dyld stub code contains references to this,
// but it should never be called because we treat
void *data
)
{
- if (lookupHashTable(table, (StgWord)key) == NULL)
- {
+#define GHC_CONC "base_GHCziConc"
+
+ if (lookupHashTable(table, (StgWord)key) == NULL)
+ {
insertStrHashTable(table, (StgWord)key, data);
return;
- }
- debugBelch(
+ }
+ if (strncmp(key, GHC_CONC, strlen(GHC_CONC)) == 0) {
+ /* see NOTE [io-manager-ghci] */
+ return;
+ }
+ debugBelch(
"\n\n"
"GHCi runtime linker: fatal error: I found a duplicate definition for symbol\n"
" %s\n"
"\n",
(char*)key,
obj_name
- );
- exit(1);
+ );
+ exit(1);
}
/* -----------------------------------------------------------------------------
* initialize the object linker
initTimer();
startTimer();
+#if defined(THREADED_RTS)
+ cap = ioManagerStartCap(cap);
+#endif
+
cap = rts_evalStableIO(cap, entry, NULL); // run the action
rts_checkSchedStatus("forkProcess",cap);
, "-u", "_base_GHCziConc_ensureIOManagerIsRunning_closure"
, "-u", "_base_GHCziConc_runSparks_closure"
, "-u", "_base_GHCziConc_runHandlers_closure"
+ , "-u", "_base_GHCziConc_pendingDelays_closure"
+ , "-u", "_base_GHCziConc_pendingEvents_closure"
+ , "-u", "_base_GHCziConc_ioManagerThread_closure"
+#if !defined(mingw32_HOST_OS)
+ , "-u", "_base_GHCziConc_prodding_closure"
+ , "-u", "_base_GHCziConc_sync_closure"
+ , "-u", "_base_GHCziConc_stick_closure"
+#endif
#else
"-u", "ghczmprim_GHCziTypes_Izh_static_info"
, "-u", "ghczmprim_GHCziTypes_Czh_static_info"
, "-u", "base_GHCziConc_ensureIOManagerIsRunning_closure"
, "-u", "base_GHCziConc_runSparks_closure"
, "-u", "base_GHCziConc_runHandlers_closure"
+ , "-u", "base_GHCziConc_pendingDelays_closure"
+ , "-u", "base_GHCziConc_pendingEvents_closure"
+ , "-u", "base_GHCziConc_ioManagerThread_closure"
+#if !defined(mingw32_HOST_OS)
+ , "-u", "base_GHCziConc_prodding_closure"
+ , "-u", "base_GHCziConc_sync_closure"
+ , "-u", "base_GHCziConc_stick_closure"
+#endif
#endif
/* Pick up static libraries in preference over dynamic if in earlier search
}
}
+Capability *
+ioManagerStartCap (Capability *cap)
+{
+ return rts_evalIO(cap,&base_GHCziConc_ensureIOManagerIsRunning_closure,NULL);
+}
+
void
ioManagerStart (void)
{
Capability *cap;
if (io_manager_pipe < 0) {
cap = rts_lock();
- cap = rts_evalIO(cap,&base_GHCziConc_ensureIOManagerIsRunning_closure,NULL);
+ cap = ioManagerStartCap(cap);
rts_unlock(cap);
}
}
void startSignalHandlers(Capability *cap);
#endif
+Capability *ioManagerStartCap (Capability *cap);
+
extern StgInt *signal_handlers;
END_RTS_PRIVATE