Free Win32 Handles on shutdown
authorSimon Marlow <simonmar@microsoft.com>
Fri, 25 Aug 2006 08:44:35 +0000 (08:44 +0000)
committerSimon Marlow <simonmar@microsoft.com>
Fri, 25 Aug 2006 08:44:35 +0000 (08:44 +0000)
patch from #878

rts/win32/AsyncIO.c
rts/win32/ConsoleHandler.c
rts/win32/IOManager.c
rts/win32/Ticker.c
rts/win32/WorkQueue.c

index 2ff92d9..3f99113 100644 (file)
@@ -45,8 +45,8 @@ typedef struct CompletedReq {
 #define MAX_REQUESTS 200
 
 static CRITICAL_SECTION queue_lock;
-static HANDLE           completed_req_event;
-static HANDLE           abandon_req_wait;
+static HANDLE           completed_req_event = INVALID_HANDLE_VALUE;
+static HANDLE           abandon_req_wait = INVALID_HANDLE_VALUE;
 static HANDLE           wait_handles[2];
 static CompletedReq     completedTable[MAX_REQUESTS];
 static int              completed_hw;
@@ -173,7 +173,18 @@ startupAsyncIO()
 void
 shutdownAsyncIO()
 {
-    CloseHandle(completed_req_event);
+    if (completed_req_event != INVALID_HANDLE_VALUE) {
+        CloseHandle(completed_req_event);
+       completed_req_event = INVALID_HANDLE_VALUE;
+    }
+    if (abandon_req_wait != INVALID_HANDLE_VALUE) {
+        CloseHandle(abandon_req_wait);
+       abandon_req_wait = INVALID_HANDLE_VALUE;
+    }
+    if (completed_table_sema != NULL) {
+        CloseHandle(completed_table_sema);
+       completed_table_sema = NULL;
+    }
     ShutdownIOManager();
 }
 
index cc0365b..308b77b 100644 (file)
@@ -46,6 +46,14 @@ initUserSignals(void)
     return;
 }
 
+void
+finiUserSignals(void)
+{
+    if (hConsoleEvent != INVALID_HANDLE_VALUE) {
+        CloseHandle(hConsoleEvent);
+    }
+}
+
 /*
  * Function: shutdown_handler()
  *
index a67c350..e69b8bc 100644 (file)
@@ -80,6 +80,9 @@ IOWorkerProc(PVOID param)
 
        if (rc == WAIT_OBJECT_0) {
            // we received the exit event
+           EnterCriticalSection(&iom->manLock);
+           ioMan->numWorkers--;
+           LeaveCriticalSection(&iom->manLock);
            return 0;
        }
 
@@ -435,12 +438,23 @@ AddProcRequest ( void* proc,
 
 void ShutdownIOManager ( void )
 {
-  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);
+  
+    /* 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);
+    free(ioMan);
+    ioMan = NULL;
 }
 
 /* Keep track of WorkItems currently being serviced. */
index ab791d8..9fa40eb 100644 (file)
@@ -115,6 +115,7 @@ stopTicker(void)
            }
            if (exitCode != STILL_ACTIVE) {
                tickThread = INVALID_HANDLE_VALUE;
+               CloseHandle(hStopEvent);
                return 0;
            }
            TerminateThread(tickThread, 0);
index 85a2360..a0b06f3 100644 (file)
@@ -45,8 +45,7 @@ NewWorkQueue()
     return wq;
   }
     
-  wq->head   = 0;
-  wq->tail   = 0;
+  memset(wq, 0, sizeof *wq);
   
   InitializeCriticalSection(&wq->queueLock);
   wq->workAvailable = newSemaphore(0, WORKQUEUE_SIZE);
@@ -65,6 +64,15 @@ NewWorkQueue()
 void
 FreeWorkQueue ( WorkQueue* pq )
 {
+  int i;
+
+  /* Free any remaining work items. */
+  for (i = 0; i < WORKQUEUE_SIZE; i++) {
+    if (pq->items[i] != NULL) {
+      free(pq->items[i]);
+    }
+  }
+
   /* Close the semaphores; any threads blocked waiting
    * on either will as a result be woken up.
    */ 
@@ -72,7 +80,7 @@ FreeWorkQueue ( WorkQueue* pq )
     CloseHandle(pq->workAvailable);
   }
   if ( pq->roomAvailable ) {
-    CloseHandle(pq->workAvailable);
+    CloseHandle(pq->roomAvailable);
   }
   free(pq);
   return;