Commit eb5791fe authored by Simon Marlow's avatar Simon Marlow

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.
parent 681aad99
......@@ -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 */
......
......@@ -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;
......
......@@ -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);
......
......@@ -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. */
......
......@@ -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
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment