summaryrefslogtreecommitdiff
path: root/rts/win32
diff options
context:
space:
mode:
authorSimon Marlow <simonmar@microsoft.com>2006-08-25 08:44:35 +0000
committerSimon Marlow <simonmar@microsoft.com>2006-08-25 08:44:35 +0000
commit610de7d17e09318272b7516bd9b97e8b2cbd170c (patch)
tree68dc1bbe4707688bdc7aa74ab12ce7c591e4c64a /rts/win32
parentedad06244b0a542d6b5c9ce3f3cd72941c5be804 (diff)
downloadhaskell-610de7d17e09318272b7516bd9b97e8b2cbd170c.tar.gz
Free Win32 Handles on shutdown
patch from #878
Diffstat (limited to 'rts/win32')
-rw-r--r--rts/win32/AsyncIO.c17
-rw-r--r--rts/win32/ConsoleHandler.c8
-rw-r--r--rts/win32/IOManager.c26
-rw-r--r--rts/win32/Ticker.c1
-rw-r--r--rts/win32/WorkQueue.c14
5 files changed, 54 insertions, 12 deletions
diff --git a/rts/win32/AsyncIO.c b/rts/win32/AsyncIO.c
index 2ff92d9642..3f99113b7f 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 cc0365b344..308b77bfcc 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 a67c3504c1..e69b8bc885 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 ab791d8dc7..9fa40ebe52 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 85a23608be..a0b06f3638 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;