Don't Terminate the ticker thread (#3748)
authorSimon Marlow <marlowsd@gmail.com>
Wed, 27 Jan 2010 13:54:30 +0000 (13:54 +0000)
committerSimon Marlow <marlowsd@gmail.com>
Wed, 27 Jan 2010 13:54:30 +0000 (13:54 +0000)
rts/RtsStartup.c
rts/Ticker.h
rts/Timer.c
rts/Timer.h
rts/posix/Itimer.c
rts/win32/Ticker.c

index f0b2598..8e2eac4 100644 (file)
@@ -370,7 +370,7 @@ hs_exit_(rtsBool wait_foreign)
 
     /* stop the ticker */
     stopTimer();
-    exitTimer();
+    exitTimer(wait_foreign);
 
     // set the terminal settings back to what they were
 #if !defined(mingw32_HOST_OS)    
index 3e62622..37c2696 100644 (file)
@@ -16,7 +16,7 @@ typedef void (*TickProc)(int);
 void initTicker  (nat ms, TickProc handle_tick);
 void startTicker (void);
 void stopTicker  (void);
-void exitTicker  (void);
+void exitTicker  (rtsBool wait);
 
 END_RTS_PRIVATE
 
index 8c178a0..a5d42fb 100644 (file)
@@ -114,9 +114,9 @@ stopTimer(void)
 }
 
 void
-exitTimer(void)
+exitTimer (rtsBool wait)
 {
     if (RtsFlags.MiscFlags.tickInterval != 0) {
-        exitTicker();
+        exitTicker(wait);
     }
 }
index f0b5459..b03ef06 100644 (file)
@@ -10,6 +10,6 @@
 #define TIMER_H
 
 RTS_PRIVATE void initTimer (void);
-RTS_PRIVATE void exitTimer (void);
+RTS_PRIVATE void exitTimer (rtsBool wait);
 
 #endif /* TIMER_H */
index 3a09e80..2dbf32d 100644 (file)
@@ -221,7 +221,7 @@ stopTicker(void)
 }
 
 void
-exitTicker(void)
+exitTicker (rtsBool wait STG_UNUSED)
 {
 #if defined(USE_TIMER_CREATE)
     timer_delete(timer);
index 6be1b3a..929e6f4 100644 (file)
@@ -127,7 +127,7 @@ stopTicker(void)
 }
 
 void
-exitTicker(void)
+exitTicker (rtsBool wait)
 {
     // We must wait for the ticker thread to terminate, since if we
     // are in a DLL that is about to be unloaded, the ticker thread
@@ -138,10 +138,20 @@ exitTicker(void)
        DWORD exitCode;
         ticker_state = TickerExit;
        SetEvent(hStopEvent);
-       while (1) {
-           WaitForSingleObject(tickThread, 20);
+       while (wait) {
+            // See #3748:
+            //
+            // when the RTS is compiled into a DLL (wait==rtsTrue),
+            // the ticker thread must stop before we exit, or chaos
+            // will ensue.  We can't kill it, because it may be
+            // holding a lock.
+            //
+            // When not compiled into a DLL, we wait for
+            // the thread out of courtesy, but give up after 200ms if
+            // it still hasn't stopped.
+           WaitForSingleObject(tickThread, 200);
            if (!GetExitCodeThread(tickThread, &exitCode)) {
-               return 1;
+               return;
            }
            if (exitCode != STILL_ACTIVE) {
                tickThread = INVALID_HANDLE_VALUE;
@@ -149,9 +159,8 @@ exitTicker(void)
                    CloseHandle(hStopEvent);
                    hStopEvent = INVALID_HANDLE_VALUE;
                }
-               return 0;
+               return;
            }
-           TerminateThread(tickThread, 0);
        }
     }
 }