X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=rts%2Fwin32%2FThrIOManager.c;h=f48b20387e74e11e968bcfbb1599f235023b717f;hb=723365de1b9ab1b8a8cf59a936624891d075e554;hp=76747c2376dc44b2caa8e980741f6ca3b92a90bf;hpb=150cc9e2e4657cc58bd7ec4c15e5cb72f2e1c0f6;p=ghc-hetmet.git diff --git a/rts/win32/ThrIOManager.c b/rts/win32/ThrIOManager.c index 76747c2..f48b203 100644 --- a/rts/win32/ThrIOManager.c +++ b/rts/win32/ThrIOManager.c @@ -8,7 +8,7 @@ * ---------------------------------------------------------------------------*/ #include "Rts.h" -#include "ThrIOManager.h" +#include "IOManager.h" #include "Prelude.h" #include @@ -21,6 +21,15 @@ static HANDLE io_manager_event = INVALID_HANDLE_VALUE; // spurios wakeups are returned as zero. // console events are ((event<<1) | 1) +#if defined(THREADED_RTS) + +#define EVENT_BUFSIZ 256 +Mutex event_buf_mutex; +StgWord32 event_buf[EVENT_BUFSIZ]; +nat next_event; + +#endif + HANDLE getIOManagerEvent (void) { @@ -30,35 +39,30 @@ getIOManagerEvent (void) #ifdef THREADED_RTS HANDLE hRes; + ACQUIRE_LOCK(&event_buf_mutex); + if (io_manager_event == INVALID_HANDLE_VALUE) { hRes = CreateEvent ( NULL, // no security attrs TRUE, // manual reset FALSE, // initial state, - "IO Manager Event" ); + NULL ); // event name: NULL for private events if (hRes == NULL) { sysErrorBelch("getIOManagerEvent"); stg_exit(EXIT_FAILURE); } io_manager_event = hRes; - return hRes; } else { - return io_manager_event; + hRes = io_manager_event; } + + RELEASE_LOCK(&event_buf_mutex); + return hRes; #else return NULL; #endif } -#if defined(THREADED_RTS) - -#define EVENT_BUFSIZ 256 -Mutex event_buf_mutex; -StgWord32 event_buf[EVENT_BUFSIZ]; -nat next_event; - -#endif - HsWord32 readIOManagerEvent (void) { @@ -68,6 +72,7 @@ readIOManagerEvent (void) HsWord32 res; ACQUIRE_LOCK(&event_buf_mutex); + if (io_manager_event != INVALID_HANDLE_VALUE) { if (next_event == 0) { res = 0; // no event to return @@ -83,7 +88,9 @@ readIOManagerEvent (void) } else { res = 0; } + RELEASE_LOCK(&event_buf_mutex); + // debugBelch("readIOManagerEvent: %d\n", res); return res; #else @@ -95,8 +102,9 @@ void sendIOManagerEvent (HsWord32 event) { #if defined(THREADED_RTS) - // debugBelch("sendIOManagerEvent: %d\n", event); ACQUIRE_LOCK(&event_buf_mutex); + + // debugBelch("sendIOManagerEvent: %d\n", event); if (io_manager_event != INVALID_HANDLE_VALUE) { if (next_event == EVENT_BUFSIZ) { errorBelch("event buffer overflowed; event dropped"); @@ -108,21 +116,28 @@ sendIOManagerEvent (HsWord32 event) event_buf[next_event++] = (StgWord32)event; } } + RELEASE_LOCK(&event_buf_mutex); #endif } -#if defined(THREADED_RTS) void ioManagerWakeup (void) { sendIOManagerEvent(IO_MANAGER_WAKEUP); } +#if defined(THREADED_RTS) void ioManagerDie (void) { sendIOManagerEvent(IO_MANAGER_DIE); + // IO_MANAGER_DIE must be idempotent, as it is called + // repeatedly by shutdownCapability(). Try conc059(threaded1) to + // illustrate the problem. + ACQUIRE_LOCK(&event_buf_mutex); + io_manager_event = INVALID_HANDLE_VALUE; + RELEASE_LOCK(&event_buf_mutex); // ToDo: wait for the IO manager to pick up the event, and // then release the Event and Mutex objects we've allocated. } @@ -137,7 +152,11 @@ ioManagerStart (void) Capability *cap; if (io_manager_event == INVALID_HANDLE_VALUE) { cap = rts_lock(); - rts_evalIO(cap,&base_GHCziConc_ensureIOManagerIsRunning_closure,NULL); +#if defined(mingw32_HOST_OS) && defined(__PIC__) + rts_evalIO(cap,_imp__base_GHCziConcziIO_ensureIOManagerIsRunning_closure,NULL); +#else + rts_evalIO(cap,&base_GHCziConcziIO_ensureIOManagerIsRunning_closure,NULL); +#endif rts_unlock(cap); } }