1 /* -----------------------------------------------------------------------------
\r
3 * (c) The GHC Team, 1998-2006
\r
5 * The IO manager thread in THREADED_RTS.
\r
6 * See also libraries/base/GHC/Conc.lhs.
\r
8 * ---------------------------------------------------------------------------*/
\r
11 #include "ThrIOManager.h"
\r
12 #include "Prelude.h"
\r
13 #include <windows.h>
\r
15 // Here's the Event that we use to wake up the IO manager thread
\r
16 static HANDLE io_manager_event = INVALID_HANDLE_VALUE;
\r
18 // must agree with values in GHC.Conc:
\r
19 #define IO_MANAGER_WAKEUP 0xffffffff
\r
20 #define IO_MANAGER_DIE 0xfffffffe
\r
21 // spurios wakeups are returned as zero.
\r
22 // console events are ((event<<1) | 1)
\r
25 getIOManagerEvent (void)
\r
27 // This function has to exist even in the non-THREADED_RTS,
\r
28 // because code in GHC.Conc refers to it. It won't ever be called
\r
29 // unless we're in the threaded RTS, however.
\r
33 if (io_manager_event == INVALID_HANDLE_VALUE) {
\r
34 hRes = CreateEvent ( NULL, // no security attrs
\r
35 TRUE, // manual reset
\r
36 FALSE, // initial state,
\r
37 "IO Manager Event" );
\r
39 sysErrorBelch("getIOManagerEvent");
\r
40 stg_exit(EXIT_FAILURE);
\r
42 io_manager_event = hRes;
\r
45 return io_manager_event;
\r
53 #if defined(THREADED_RTS)
\r
55 #define EVENT_BUFSIZ 256
\r
56 Mutex event_buf_mutex;
\r
57 StgWord32 event_buf[EVENT_BUFSIZ];
\r
63 readIOManagerEvent (void)
\r
65 // This function must exist even in non-THREADED_RTS,
\r
66 // see getIOManagerEvent() above.
\r
67 #if defined(THREADED_RTS)
\r
70 if (io_manager_event != INVALID_HANDLE_VALUE) {
\r
71 ACQUIRE_LOCK(&event_buf_mutex);
\r
72 if (next_event == 0) {
\r
73 res = 0; // no event to return
\r
75 res = (HsWord32)(event_buf[--next_event]);
\r
76 if (next_event == 0) {
\r
77 if (!ResetEvent(io_manager_event)) {
\r
78 sysErrorBelch("readIOManagerEvent");
\r
79 stg_exit(EXIT_FAILURE);
\r
83 RELEASE_LOCK(&event_buf_mutex);
\r
87 // debugBelch("readIOManagerEvent: %d\n", res);
\r
95 sendIOManagerEvent (HsWord32 event)
\r
97 #if defined(THREADED_RTS)
\r
98 // debugBelch("sendIOManagerEvent: %d\n", event);
\r
99 if (io_manager_event != INVALID_HANDLE_VALUE) {
\r
100 ACQUIRE_LOCK(&event_buf_mutex);
\r
101 if (next_event == EVENT_BUFSIZ) {
\r
102 errorBelch("event buffer overflowed; event dropped");
\r
104 if (!SetEvent(io_manager_event)) {
\r
105 sysErrorBelch("sendIOManagerEvent");
\r
106 stg_exit(EXIT_FAILURE);
\r
108 event_buf[next_event++] = (StgWord32)event;
\r
110 RELEASE_LOCK(&event_buf_mutex);
\r
115 #if defined(THREADED_RTS)
\r
117 ioManagerWakeup (void)
\r
119 sendIOManagerEvent(IO_MANAGER_WAKEUP);
\r
123 ioManagerDie (void)
\r
125 sendIOManagerEvent(IO_MANAGER_DIE);
\r
126 // ToDo: wait for the IO manager to pick up the event, and
\r
127 // then release the Event and Mutex objects we've allocated.
\r
131 ioManagerStart (void)
\r
133 initMutex(&event_buf_mutex);
\r
136 // Make sure the IO manager thread is running
\r
138 if (io_manager_event == INVALID_HANDLE_VALUE) {
\r
140 rts_evalIO(cap,&base_GHCziConc_ensureIOManagerIsRunning_closure,NULL);
\r