#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;
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();
}
return;
}
+void
+finiUserSignals(void)
+{
+ if (hConsoleEvent != INVALID_HANDLE_VALUE) {
+ CloseHandle(hConsoleEvent);
+ }
+}
+
/*
* Function: shutdown_handler()
*
if (rc == WAIT_OBJECT_0) {
// we received the exit event
+ EnterCriticalSection(&iom->manLock);
+ ioMan->numWorkers--;
+ LeaveCriticalSection(&iom->manLock);
return 0;
}
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. */
}
if (exitCode != STILL_ACTIVE) {
tickThread = INVALID_HANDLE_VALUE;
+ CloseHandle(hStopEvent);
return 0;
}
TerminateThread(tickThread, 0);
return wq;
}
- wq->head = 0;
- wq->tail = 0;
+ memset(wq, 0, sizeof *wq);
InitializeCriticalSection(&wq->queueLock);
wq->workAvailable = newSemaphore(0, WORKQUEUE_SIZE);
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.
*/
CloseHandle(pq->workAvailable);
}
if ( pq->roomAvailable ) {
- CloseHandle(pq->workAvailable);
+ CloseHandle(pq->roomAvailable);
}
free(pq);
return;