From: Simon Marlow Date: Fri, 25 Aug 2006 08:44:35 +0000 (+0000) Subject: Free Win32 Handles on shutdown X-Git-Tag: Before_FC_branch_merge~133 X-Git-Url: http://git.megacz.com/?p=ghc-hetmet.git;a=commitdiff_plain;h=610de7d17e09318272b7516bd9b97e8b2cbd170c Free Win32 Handles on shutdown patch from #878 --- diff --git a/rts/win32/AsyncIO.c b/rts/win32/AsyncIO.c index 2ff92d9..3f99113 100644 --- a/rts/win32/AsyncIO.c +++ b/rts/win32/AsyncIO.c @@ -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(); } diff --git a/rts/win32/ConsoleHandler.c b/rts/win32/ConsoleHandler.c index cc0365b..308b77b 100644 --- a/rts/win32/ConsoleHandler.c +++ b/rts/win32/ConsoleHandler.c @@ -46,6 +46,14 @@ initUserSignals(void) return; } +void +finiUserSignals(void) +{ + if (hConsoleEvent != INVALID_HANDLE_VALUE) { + CloseHandle(hConsoleEvent); + } +} + /* * Function: shutdown_handler() * diff --git a/rts/win32/IOManager.c b/rts/win32/IOManager.c index a67c350..e69b8bc 100644 --- a/rts/win32/IOManager.c +++ b/rts/win32/IOManager.c @@ -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. */ diff --git a/rts/win32/Ticker.c b/rts/win32/Ticker.c index ab791d8..9fa40eb 100644 --- a/rts/win32/Ticker.c +++ b/rts/win32/Ticker.c @@ -115,6 +115,7 @@ stopTicker(void) } if (exitCode != STILL_ACTIVE) { tickThread = INVALID_HANDLE_VALUE; + CloseHandle(hStopEvent); return 0; } TerminateThread(tickThread, 0); diff --git a/rts/win32/WorkQueue.c b/rts/win32/WorkQueue.c index 85a2360..a0b06f3 100644 --- a/rts/win32/WorkQueue.c +++ b/rts/win32/WorkQueue.c @@ -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;