X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=rts%2Fwin32%2FIOManager.c;h=81dedda569874775114bce599334ac720b3662e0;hb=8f1192a43e20954c368b466be6af8410a9860d14;hp=a67c3504c1788d738be06101c6ad582a9f66141c;hpb=0065d5ab628975892cea1ec7303f968c3338cbe1;p=ghc-hetmet.git diff --git a/rts/win32/IOManager.c b/rts/win32/IOManager.c index a67c350..81dedda 100644 --- a/rts/win32/IOManager.c +++ b/rts/win32/IOManager.c @@ -4,6 +4,9 @@ * * (c) sof, 2002-2003. */ + +#if !defined(THREADED_RTS) + #include "Rts.h" #include "IOManager.h" #include "WorkQueue.h" @@ -80,6 +83,9 @@ IOWorkerProc(PVOID param) if (rc == WAIT_OBJECT_0) { // we received the exit event + EnterCriticalSection(&iom->manLock); + ioMan->numWorkers--; + LeaveCriticalSection(&iom->manLock); return 0; } @@ -184,7 +190,7 @@ IOWorkerProc(PVOID param) * * Note: Sleep() is in milliseconds, not micros. */ - Sleep(work->workData.delayData.msecs / 1000); + Sleep((work->workData.delayData.msecs + 999) / 1000); len = work->workData.delayData.msecs; complData = NULL; fd = 0; @@ -217,10 +223,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 +343,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 @@ -433,14 +443,29 @@ AddProcRequest ( void* proc, return depositWorkItem(reqID, wItem); } -void ShutdownIOManager ( void ) +void ShutdownIOManager ( rtsBool wait_threads ) { - 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); + + if (wait_threads) { + /* 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); + DeleteCriticalSection(&ioMan->active_work_lock); + DeleteCriticalSection(&ioMan->manLock); + free(ioMan); + ioMan = NULL; + } } /* Keep track of WorkItems currently being serviced. */ @@ -508,3 +533,5 @@ abandonWorkRequest ( int reqID ) */ LeaveCriticalSection(&ioMan->active_work_lock); } + +#endif