Ensure runhaskell is rebuild in stage2
[ghc-hetmet.git] / rts / win32 / IOManager.c
index a67c350..81dedda 100644 (file)
@@ -4,6 +4,9 @@
  *
  * (c) sof, 2002-2003.
  */
+
+#if !defined(THREADED_RTS)
+
 #include "Rts.h"
 #include "IOManager.h"
 #include "WorkQueue.h"
@@ -80,6 +83,9 @@ IOWorkerProc(PVOID param)
 
        if (rc == WAIT_OBJECT_0) {
            // we received the exit event
+           EnterCriticalSection(&iom->manLock);
+           ioMan->numWorkers--;
+           LeaveCriticalSection(&iom->manLock);
            return 0;
        }
 
@@ -184,7 +190,7 @@ IOWorkerProc(PVOID param)
                     * 
                     * Note: Sleep() is in milliseconds, not micros.
                     */
-                   Sleep(work->workData.delayData.msecs / 1000);
+                   Sleep((work->workData.delayData.msecs + 999) / 1000);
                    len = work->workData.delayData.msecs;
                    complData = NULL;
                    fd = 0;
@@ -217,10 +223,16 @@ IOWorkerProc(PVOID param)
                free(work);
            } else {
                fprintf(stderr, "unable to fetch work; fatal.\n"); fflush(stderr);
+               EnterCriticalSection(&iom->manLock);
+               ioMan->numWorkers--;
+               LeaveCriticalSection(&iom->manLock);
                return 1;
            }
        } else {
            fprintf(stderr, "waiting failed (%lu); fatal.\n", rc); fflush(stderr);
+           EnterCriticalSection(&iom->manLock);
+           ioMan->numWorkers--;
+           LeaveCriticalSection(&iom->manLock);
            return 1;
        }
     }
@@ -331,14 +343,12 @@ depositWorkItem( unsigned int reqID,
        if ( (ioMan->workersIdle < ioMan->queueSize) ) {
            /* No, go ahead and create another. */
            ioMan->numWorkers++;
-           LeaveCriticalSection(&ioMan->manLock);
-           NewIOWorkerThread(ioMan);
-       } else {
-           LeaveCriticalSection(&ioMan->manLock);
+           if (!NewIOWorkerThread(ioMan)) {
+               ioMan->numWorkers--;
+           }
        }
-    } else {
-       LeaveCriticalSection(&ioMan->manLock);
     }
+    LeaveCriticalSection(&ioMan->manLock);
   
     if (SubmitWork(ioMan->workQueue,wItem)) {
        /* Note: the work item has potentially been consumed by a worker thread
@@ -433,14 +443,29 @@ AddProcRequest ( void* proc,
     return depositWorkItem(reqID, wItem);
 }
 
-void ShutdownIOManager ( void )
+void ShutdownIOManager ( rtsBool wait_threads )
 {
-  SetEvent(ioMan->hExitEvent);
-  // ToDo: we can't free this now, because the worker thread(s)
-  // haven't necessarily finished with it yet.  Perhaps it should
-  // have a reference count or something.
-  // free(ioMan);
-  // ioMan = NULL;
+    int num;
+
+    SetEvent(ioMan->hExitEvent);
+  
+    if (wait_threads) {
+        /* Wait for all worker threads to die. */
+        for (;;) {
+            EnterCriticalSection(&ioMan->manLock);
+            num = ioMan->numWorkers;
+            LeaveCriticalSection(&ioMan->manLock);
+            if (num == 0)
+                break;
+            Sleep(10);
+        }
+        FreeWorkQueue(ioMan->workQueue);
+        CloseHandle(ioMan->hExitEvent);
+        DeleteCriticalSection(&ioMan->active_work_lock);
+        DeleteCriticalSection(&ioMan->manLock);
+        free(ioMan);
+        ioMan = NULL;
+    }
 }
 
 /* Keep track of WorkItems currently being serviced. */
@@ -508,3 +533,5 @@ abandonWorkRequest ( int reqID )
      */
     LeaveCriticalSection(&ioMan->active_work_lock);
 }
+
+#endif