From: Simon Marlow Date: Wed, 25 Jul 2007 13:55:04 +0000 (+0000) Subject: FIX #1177, partially at least. X-Git-Url: http://git.megacz.com/?p=ghc-hetmet.git;a=commitdiff_plain;h=eb5791fe867f6441d270344298678f45ed4a75e4 FIX #1177, partially at least. Now we don't wait for outstanding IO requests when shutting down at program exit time, but we still wait when shutting down a DLL (via hs_exit()). There ought to be a better way to do this, but terminating the threads forcibly is not a good idea (it never is: the thread might be holding a mutex when it dies, for example). I plan to add some docs to the user guide to describe how to shut down a DLL properly. --- diff --git a/rts/RtsStartup.c b/rts/RtsStartup.c index 8be4044..4f5b1c7 100644 --- a/rts/RtsStartup.c +++ b/rts/RtsStartup.c @@ -494,7 +494,7 @@ hs_exit_(rtsBool wait_foreign) #endif #if defined(mingw32_HOST_OS) && !defined(THREADED_RTS) - shutdownAsyncIO(); + shutdownAsyncIO(wait_foreign); #endif /* free hash table storage */ diff --git a/rts/win32/AsyncIO.c b/rts/win32/AsyncIO.c index cd0cf38..20de8bb 100644 --- a/rts/win32/AsyncIO.c +++ b/rts/win32/AsyncIO.c @@ -174,9 +174,9 @@ startupAsyncIO() } void -shutdownAsyncIO() +shutdownAsyncIO(rtsBool wait_threads) { - ShutdownIOManager(); + ShutdownIOManager(wait_threads); if (completed_req_event != INVALID_HANDLE_VALUE) { CloseHandle(completed_req_event); completed_req_event = INVALID_HANDLE_VALUE; diff --git a/rts/win32/AsyncIO.h b/rts/win32/AsyncIO.h index 2077ea0..ffbe71e 100644 --- a/rts/win32/AsyncIO.h +++ b/rts/win32/AsyncIO.h @@ -15,7 +15,7 @@ addIORequest(int fd, extern unsigned int addDelayRequest(int msecs); extern unsigned int addDoProcRequest(void* proc, void* param); extern int startupAsyncIO(void); -extern void shutdownAsyncIO(void); +extern void shutdownAsyncIO(rtsBool wait_threads); extern int awaitRequests(rtsBool wait); diff --git a/rts/win32/IOManager.c b/rts/win32/IOManager.c index 6af4245..6e7cd25 100644 --- a/rts/win32/IOManager.c +++ b/rts/win32/IOManager.c @@ -443,25 +443,27 @@ AddProcRequest ( void* proc, return depositWorkItem(reqID, wItem); } -void ShutdownIOManager ( void ) +void ShutdownIOManager ( rtsBool wait_threads ) { 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); + 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); + free(ioMan); + ioMan = NULL; } - FreeWorkQueue(ioMan->workQueue); - CloseHandle(ioMan->hExitEvent); - free(ioMan); - ioMan = NULL; } /* Keep track of WorkItems currently being serviced. */ diff --git a/rts/win32/IOManager.h b/rts/win32/IOManager.h index 4893e23..9555ee5 100644 --- a/rts/win32/IOManager.h +++ b/rts/win32/IOManager.h @@ -84,7 +84,7 @@ extern CompletionProc onComplete; * Starting up and shutting down. */ extern BOOL StartIOManager ( void ); -extern void ShutdownIOManager ( void ); +extern void ShutdownIOManager ( rtsBool wait_threads ); /* * Adding I/O and delay requests. With each request a