0df8023e8694345f78b275f5bcefdd89f46eddfe
[ghc-hetmet.git] / ghc / rts / win32 / AwaitEvent.c
1 /*
2  * Wait/check for external events. Periodically, the
3  * Scheduler checks for the completion of external operations,
4  * like the expiration of timers, completion of I/O requests
5  * issued by Haskell threads.
6  *
7  * If the Scheduler is otherwise out of work, it'll block
8  * herein waiting for external events to occur.
9  *
10  * This file mirrors the select()-based functionality 
11  * for POSIX / Unix platforms in rts/Select.c, but for
12  * Win32.
13  *
14  */
15 #include "Rts.h"
16 #include "Schedule.h"
17 #include <windows.h>
18 #include "win32/AsyncIO.h"
19 #if defined(RTS_SUPPORTS_THREADS)
20 #include "Capability.h"
21 #endif
22
23 void
24 awaitEvent(rtsBool wait)
25 {
26   int ret;
27
28   do {
29     /* Try to de-queue completed IO requests
30      */
31     RELEASE_LOCK(&sched_mutex);
32     ret = awaitRequests(wait);
33     ACQUIRE_LOCK(&sched_mutex);
34     if (!ret) { 
35       return; /* still hold the lock */
36     }
37
38     /* we were interrupted, return to the scheduler immediately.
39      */
40     if (interrupted) {
41       return; /* still hold the lock */
42     }
43
44     /* If new runnable threads have arrived, stop waiting for
45      * I/O and run them.
46      */
47     if (run_queue_hd != END_TSO_QUEUE) {
48       return; /* still hold the lock */
49     }
50
51 #ifdef RTS_SUPPORTS_THREADS
52     /* If another worker thread wants to take over,
53      * return to the scheduler
54      */
55     if (needToYieldToReturningWorker()) {
56       return; /* still hold the lock */
57     }
58 #endif
59   } while (wait && !interrupted && run_queue_hd == END_TSO_QUEUE);
60 }
61
62 #ifdef RTS_SUPPORTS_THREADS
63 void
64 wakeBlockedWorkerThread()
65 {
66   abandonRequestWait();
67 }
68 #endif
69