X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=rts%2Fwin32%2FThrIOManager.c;h=f48b20387e74e11e968bcfbb1599f235023b717f;hb=cdbc494c6932d2ffa32d211bb988a635124bf016;hp=b0da0deee9427273c32bee587d4f5f76f9d79747;hpb=80a766fdb6864eae613962e43ad9eb371e0ce80c;p=ghc-hetmet.git diff --git a/rts/win32/ThrIOManager.c b/rts/win32/ThrIOManager.c index b0da0de..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,49 +39,45 @@ 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 - -StgWord32 +HsWord32 readIOManagerEvent (void) { // This function must exist even in non-THREADED_RTS, // see getIOManagerEvent() above. #if defined(THREADED_RTS) - StgWord32 res; + HsWord32 res; ACQUIRE_LOCK(&event_buf_mutex); + if (io_manager_event != INVALID_HANDLE_VALUE) { if (next_event == 0) { res = 0; // no event to return } else { - res = event_buf[--next_event]; + res = (HsWord32)(event_buf[--next_event]); if (next_event == 0) { if (!ResetEvent(io_manager_event)) { sysErrorBelch("readIOManagerEvent"); @@ -83,7 +88,9 @@ readIOManagerEvent (void) } else { res = 0; } + RELEASE_LOCK(&event_buf_mutex); + // debugBelch("readIOManagerEvent: %d\n", res); return res; #else @@ -92,11 +99,12 @@ readIOManagerEvent (void) } void -sendIOManagerEvent (StgWord32 event) +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"); @@ -105,24 +113,31 @@ sendIOManagerEvent (StgWord32 event) sysErrorBelch("sendIOManagerEvent"); stg_exit(EXIT_FAILURE); } - event_buf[next_event++] = 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); } }