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.
7 * If the Scheduler is otherwise out of work, it'll block
8 * herein waiting for external events to occur.
10 * This file mirrors the select()-based functionality
11 * for POSIX / Unix platforms in rts/Select.c, but for
18 #include "win32/AsyncIO.h"
19 #if defined(RTS_SUPPORTS_THREADS)
20 #include "Capability.h"
23 // Used to avoid calling abandonRequestWait() if we don't need to.
24 // Protected by sched_mutex.
25 static nat workerWaitingForRequests = 0;
28 awaitEvent(rtsBool wait)
32 #ifdef RTS_SUPPORTS_THREADS
33 // Small optimisation: we don't want the waiting thread to wake
34 // up straight away just because a previous returning worker has
35 // called abandonRequestWait(). If the event is no longer needed,
36 // reset it. We must do this inside the sched_mutex.
37 if (!needToYieldToReturningWorker()) {
38 resetAbandonRequestWait();
43 /* Try to de-queue completed IO requests
45 workerWaitingForRequests = 1;
46 RELEASE_LOCK(&sched_mutex);
47 ret = awaitRequests(wait);
48 ACQUIRE_LOCK(&sched_mutex);
49 workerWaitingForRequests = 0;
51 return; /* still hold the lock */
54 // Return to the scheduler if:
56 // - we were interrupted
57 // - new threads have arrived
58 // - another worker wants to take over (RTS_SUPPORTS_THREADS)
62 && run_queue_hd == END_TSO_QUEUE
63 #ifdef RTS_SUPPORTS_THREADS
64 && !needToYieldToReturningWorker()
69 #ifdef RTS_SUPPORTS_THREADS
71 wakeBlockedWorkerThread()
73 if (workerWaitingForRequests) {