FIX #1177, partially at least.
authorSimon Marlow <simonmar@microsoft.com>
Wed, 25 Jul 2007 13:55:04 +0000 (13:55 +0000)
committerSimon Marlow <simonmar@microsoft.com>
Wed, 25 Jul 2007 13:55:04 +0000 (13:55 +0000)
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.

rts/RtsStartup.c
rts/win32/AsyncIO.c
rts/win32/AsyncIO.h
rts/win32/IOManager.c
rts/win32/IOManager.h

index 8be4044..4f5b1c7 100644 (file)
@@ -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 */
index cd0cf38..20de8bb 100644 (file)
@@ -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;
index 2077ea0..ffbe71e 100644 (file)
@@ -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);
 
index 6af4245..6e7cd25 100644 (file)
@@ -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. */
index 4893e23..9555ee5 100644 (file)
@@ -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