[project @ 2005-10-24 09:37:08 by simonmar]
[ghc-hetmet.git] / ghc / rts / win32 / AsyncIO.c
index a0e03cb..12893f3 100644 (file)
@@ -9,6 +9,7 @@
 #include <windows.h>
 #include <stdio.h>
 #include "Schedule.h"
+#include "RtsFlags.h"
 #include "Capability.h"
 #include "win32/AsyncIO.h"
 #include "win32/IOManager.h"
@@ -49,6 +50,7 @@ static HANDLE           abandon_req_wait;
 static HANDLE           wait_handles[2];
 static CompletedReq     completedTable[MAX_REQUESTS];
 static int              completed_hw;
+static HANDLE           completed_table_sema;
 static int              issued_reqs;
 
 static void
@@ -58,11 +60,22 @@ onIOComplete(unsigned int reqID,
             void* buf STG_UNUSED,
             int   errCode)
 {
-    /* Deposit result of request in queue/table */
+    DWORD dwRes;
+    /* Deposit result of request in queue/table..when there's room. */
+    dwRes = WaitForSingleObject(completed_table_sema, INFINITE);
+    switch (dwRes) {
+    case WAIT_OBJECT_0:
+       break;
+    default:
+       /* Not likely */
+       fprintf(stderr, "onIOComplete: failed to grab table semaphore, dropping request 0x%x\n", reqID);
+       fflush(stderr);
+       return;
+    }
     EnterCriticalSection(&queue_lock);
     if (completed_hw == MAX_REQUESTS) {
-       /* Not likely */
-       fprintf(stderr, "Request table overflow (%d); dropping.\n", reqID);
+       /* Shouldn't happen */
+       fprintf(stderr, "onIOComplete: ERROR -- Request table overflow (%d); dropping.\n", reqID);
        fflush(stderr);
     } else {
 #if 0
@@ -146,8 +159,15 @@ startupAsyncIO()
     wait_handles[0] = completed_req_event;
     wait_handles[1] = abandon_req_wait;
     completed_hw = 0;
-    return ( completed_req_event != INVALID_HANDLE_VALUE &&
-            abandon_req_wait    != INVALID_HANDLE_VALUE );
+    if ( !(completed_table_sema = CreateSemaphore (NULL, MAX_REQUESTS, MAX_REQUESTS, NULL)) ) {
+       DWORD rc = GetLastError();
+       fprintf(stderr, "startupAsyncIO: CreateSemaphore failed 0x%x\n", rc);
+       fflush(stderr);
+    }
+
+    return ( completed_req_event  != INVALID_HANDLE_VALUE &&
+            abandon_req_wait     != INVALID_HANDLE_VALUE &&
+            completed_table_sema != NULL );
 }
 
 void
@@ -176,6 +196,9 @@ shutdownAsyncIO()
 int
 awaitRequests(rtsBool wait)
 {
+#ifndef THREADED_RTS
+  // none of this is actually used in the threaded RTS
+
 start:
 #if 0
     fprintf(stderr, "awaitRequests(): %d %d %d\n", issued_reqs, completed_hw, wait);
@@ -200,9 +223,11 @@ start:
            DWORD dwRes = WaitForMultipleObjects(2, wait_handles, FALSE, INFINITE);
            switch (dwRes) {
            case WAIT_OBJECT_0:
+               /* a request was completed */
                break;
            case WAIT_OBJECT_0 + 1:
            case WAIT_TIMEOUT:
+               /* timeout (unlikely) or told to abandon waiting */
                return 0;
            case WAIT_FAILED: {
                DWORD dw = GetLastError();
@@ -272,12 +297,19 @@ start:
                    break;
                }
            }
+           /* Signal that there's completed table slots available */
+           if ( !ReleaseSemaphore(completed_table_sema, 1, NULL) ) {
+               DWORD dw = GetLastError();
+               fprintf(stderr, "awaitRequests: failed to signal semaphore (error code=0x%x)\n", dw);
+               fflush(stderr);
+           }
        }
        completed_hw = 0;
        ResetEvent(completed_req_event);
        LeaveCriticalSection(&queue_lock);
        return 1;
     }
+#endif /* !THREADED_RTS */
 }
 
 /*