Refactor SrcLoc and SrcSpan
[ghc-hetmet.git] / rts / win32 / Ticker.c
index d425dd5..929e6f4 100644 (file)
@@ -3,12 +3,10 @@
  * 
  */
 #include "Rts.h"
-#include "Timer.h"
 #include "Ticker.h"
 #include <windows.h>
 #include <stdio.h>
 #include <process.h>
-#include "OSThreads.h"
 
 /*
  * Provide a timer service for the RTS, periodically
@@ -42,7 +40,7 @@ WINAPI
 TimerProc(PVOID param)
 {
   int ms = (int)param;
-  DWORD waitRes;
+  DWORD waitRes = 0;
   
   /* interpret a < 0 timeout period as 'instantaneous' */ 
   if (ms < 0) ms = 0;
@@ -53,9 +51,7 @@ TimerProc(PVOID param)
           waitRes = WaitForSingleObject(hStopEvent, ms);
           break;
       case TickerPause:
-          debugBelch("tick: pause");
           waitRes = WaitForSingleObject(hStopEvent, INFINITE);
-          debugBelch("tick: wakeup");
           break;
       case TickerExit:
           /* event has become signalled */
@@ -131,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
@@ -142,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;
@@ -153,9 +159,8 @@ exitTicker(void)
                    CloseHandle(hStopEvent);
                    hStopEvent = INVALID_HANDLE_VALUE;
                }
-               return 0;
+               return;
            }
-           TerminateThread(tickThread, 0);
        }
     }
 }