X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=rts%2Fwin32%2FIOManager.c;h=2123b8c3a49067562ba5ffc0ce51f12d08cbf308;hb=37a3e47992bd46a3cf4f6a4c6fd5b9e187e88452;hp=a67c3504c1788d738be06101c6ad582a9f66141c;hpb=0065d5ab628975892cea1ec7303f968c3338cbe1;p=ghc-hetmet.git diff --git a/rts/win32/IOManager.c b/rts/win32/IOManager.c index a67c350..2123b8c 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; } @@ -217,10 +220,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 +340,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 @@ -435,12 +442,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. */