#define RTS_GLOBALS_H
StgStablePtr getOrSetTypeableStore(StgStablePtr value);
-StgStablePtr getOrSetSignalHandlerStore(StgStablePtr value);
+StgStablePtr getOrSetGHCConcSignalHandlerStore(StgStablePtr value);
+StgStablePtr getOrSetGHCConcPendingEventsStore(StgStablePtr ptr);
+StgStablePtr getOrSetGHCConcPendingDelaysStore(StgStablePtr ptr);
+StgStablePtr getOrSetGHCConcIOManagerThreadStore(StgStablePtr ptr);
+StgStablePtr getOrSetGHCConcProddingStore(StgStablePtr ptr);
#endif /* RTS_GLOBALS_H */
#else
void setIOManagerPipe (int fd);
+void ioManagerSync (void);
#endif
// Posix implementation in posix/Signals.c
// Win32 implementation in win32/ThrIOManager.c
//
-#if defined(THREADED_RTS)
void ioManagerWakeup (void);
+#if defined(THREADED_RTS)
void ioManagerDie (void);
void ioManagerStart (void);
#endif
* even when multiple versions of the library are loaded. e.g. see
* Data.Typeable and GHC.Conc.
*
+ * If/when we switch to a dynamically-linked GHCi, this can all go
+ * away, because there would be just one copy of each library.
+ *
* ---------------------------------------------------------------------------*/
#include "PosixSource.h"
#include "Globals.h"
#include "Stable.h"
-static StgStablePtr typeableStore = 0;
-static StgStablePtr signalHandlerStore = 0;
+typedef enum {
+ TypeableStore,
+ GHCConcSignalHandlerStore,
+ GHCConcPendingEventsStore,
+ GHCConcPendingDelaysStore,
+ GHCConcIOManagerThreadStore,
+ GHCConcProddingStore,
+ MaxStoreKey
+} StoreKey;
#ifdef THREADED_RTS
Mutex globalStoreLock;
#endif
+StgStablePtr store[MaxStoreKey];
+
void
initGlobalStore(void)
{
- typeableStore = 0;
- signalHandlerStore = 0;
+ nat i;
+ for (i=0; i < MaxStoreKey; i++) {
+ store[i] = 0;
+ }
#ifdef THREADED_RTS
initMutex(&globalStoreLock);
#endif
void
exitGlobalStore(void)
{
+ nat i;
#ifdef THREADED_RTS
closeMutex(&globalStoreLock);
#endif
- if(typeableStore!=0) {
- freeStablePtr((StgStablePtr)typeableStore);
- typeableStore=0;
- }
- if(signalHandlerStore!=0) {
- freeStablePtr((StgStablePtr)signalHandlerStore);
- signalHandlerStore=0;
+ for (i=0; i < MaxStoreKey; i++) {
+ if (store[i] != 0) {
+ freeStablePtr(store[i]);
+ store[i] = 0;
+ }
}
}
-StgStablePtr
-getOrSetTypeableStore(StgStablePtr ptr)
+static StgStablePtr getOrSetKey(StoreKey key, StgStablePtr ptr)
{
- StgStablePtr ret = typeableStore;
+ StgStablePtr ret = store[key];
if(ret==0) {
#ifdef THREADED_RTS
ACQUIRE_LOCK(&globalStoreLock);
- ret=typeableStore;
+ ret = store[key];
if(ret==0) {
#endif
- typeableStore = ret = ptr;
+ store[key] = ret = ptr;
#ifdef THREADED_RTS
}
RELEASE_LOCK(&globalStoreLock);
#endif
}
return ret;
+}
+
+
+StgStablePtr
+getOrSetTypeableStore(StgStablePtr ptr)
+{
+ return getOrSetKey(TypeableStore,ptr);
}
StgStablePtr
-getOrSetSignalHandlerStore(StgStablePtr ptr)
+getOrSetGHCConcSignalHandlerStore(StgStablePtr ptr)
{
- StgStablePtr ret = signalHandlerStore;
- if(ret==0) {
-#ifdef THREADED_RTS
- ACQUIRE_LOCK(&globalStoreLock);
- ret=signalHandlerStore;
- if(ret==0) {
-#endif
- signalHandlerStore = ret = ptr;
-#ifdef THREADED_RTS
- }
- RELEASE_LOCK(&globalStoreLock);
-#endif
- }
- return ret;
+ return getOrSetKey(GHCConcSignalHandlerStore,ptr);
+}
+
+StgStablePtr
+getOrSetGHCConcPendingEventsStore(StgStablePtr ptr)
+{
+ return getOrSetKey(GHCConcPendingEventsStore,ptr);
+}
+
+StgStablePtr
+getOrSetGHCConcPendingDelaysStore(StgStablePtr ptr)
+{
+ return getOrSetKey(GHCConcPendingDelaysStore,ptr);
+}
+
+StgStablePtr
+getOrSetGHCConcIOManagerThreadStore(StgStablePtr ptr)
+{
+ return getOrSetKey(GHCConcIOManagerThreadStore,ptr);
+}
+
+StgStablePtr
+getOrSetGHCConcProddingStore(StgStablePtr ptr)
+{
+ return getOrSetKey(GHCConcProddingStore,ptr);
}
#if !defined(mingw32_HOST_OS)
#define RTS_USER_SIGNALS_SYMBOLS \
SymI_HasProto(setIOManagerPipe) \
+ SymI_HasProto(ioManagerWakeup) \
+ SymI_HasProto(ioManagerSync) \
SymI_HasProto(blockUserSignals) \
SymI_HasProto(unblockUserSignals)
#else
#define RTS_USER_SIGNALS_SYMBOLS \
+ SymI_HasProto(ioManagerWakeup) \
SymI_HasProto(sendIOManagerEvent) \
SymI_HasProto(readIOManagerEvent) \
SymI_HasProto(getIOManagerEvent) \
SymI_HasProto(forkOS_createThread) \
SymI_HasProto(freeHaskellFunctionPtr) \
SymI_HasProto(getOrSetTypeableStore) \
- SymI_HasProto(getOrSetSignalHandlerStore) \
+ SymI_HasProto(getOrSetGHCConcSignalHandlerStore) \
+ SymI_HasProto(getOrSetGHCConcPendingEventsStore) \
+ SymI_HasProto(getOrSetGHCConcPendingDelaysStore) \
+ SymI_HasProto(getOrSetGHCConcIOManagerThreadStore) \
+ SymI_HasProto(getOrSetGHCConcProddingStore) \
SymI_HasProto(genSymZh) \
SymI_HasProto(genericRaise) \
SymI_HasProto(getProgArgv) \
#define IO_MANAGER_WAKEUP 0xff
#define IO_MANAGER_DIE 0xfe
+#define IO_MANAGER_SYNC 0xfd
void
setIOManagerPipe (int fd)
{
// only called when THREADED_RTS, but unconditionally
// compiled here because GHC.Conc depends on it.
- if (io_manager_pipe < 0) {
- io_manager_pipe = fd;
- }
+ io_manager_pipe = fd;
}
-#if defined(THREADED_RTS)
void
ioManagerWakeup (void)
{
}
void
+ioManagerSync (void)
+{
+ int r;
+ // Wake up the IO Manager thread by sending a byte down its pipe
+ if (io_manager_pipe >= 0) {
+ StgWord8 byte = (StgWord8)IO_MANAGER_SYNC;
+ r = write(io_manager_pipe, &byte, 1);
+ if (r == -1) { sysErrorBelch("ioManagerSync: write"); }
+ }
+}
+
+#if defined(THREADED_RTS)
+void
ioManagerDie (void)
{
int r;