summaryrefslogtreecommitdiff
path: root/ghc/rts
diff options
context:
space:
mode:
authorSimon Marlow <simonmar@microsoft.com>2006-03-20 16:34:39 +0000
committerSimon Marlow <simonmar@microsoft.com>2006-03-20 16:34:39 +0000
commitafe67cb590a9bc1adb729e0757fd698ff10d4492 (patch)
tree05639aecc2723de8180254ed07602af30f01b0a4 /ghc/rts
parent1f5e3b2472084434edf71a89c4764d1509e8e9b0 (diff)
downloadhaskell-afe67cb590a9bc1adb729e0757fd698ff10d4492.tar.gz
stopTicker(): wait for the timer thread to exit
Diffstat (limited to 'ghc/rts')
-rw-r--r--ghc/rts/win32/Ticker.c38
1 files changed, 30 insertions, 8 deletions
diff --git a/ghc/rts/win32/Ticker.c b/ghc/rts/win32/Ticker.c
index c1390b7d76..0923fea5f0 100644
--- a/ghc/rts/win32/Ticker.c
+++ b/ghc/rts/win32/Ticker.c
@@ -8,6 +8,7 @@
#include <windows.h>
#include <stdio.h>
#include <process.h>
+#include "OSThreads.h"
/*
* Provide a timer service for the RTS, periodically
@@ -20,6 +21,7 @@
* signals.)
*/
static HANDLE hStopEvent = INVALID_HANDLE_VALUE;
+static HANDLE tickThread = INVALID_HANDLE_VALUE;
static TickProc tickProc = NULL;
@@ -38,11 +40,13 @@ unsigned
WINAPI
TimerProc(PVOID param)
{
+ return 0;
+
int ms = (int)param;
DWORD waitRes;
- /* interpret a < 0 timeout period as 'instantaneous' */
- if (ms < 0) ms = 0;
+ /* interpret a < 0 timeout period as 'instantaneous' */
+ if (ms < 0) ms = 0;
while (1) {
waitRes = WaitForSingleObject(hStopEvent, ms);
@@ -86,19 +90,37 @@ startTicker(nat ms, TickProc handle_tick)
return 0;
}
tickProc = handle_tick;
- return ( 0 != _beginthreadex(NULL,
+ tickThread = (HANDLE)(long)_beginthreadex( NULL,
0,
TimerProc,
(LPVOID)ms,
0,
- &threadId) );
+ &threadId);
+ return (tickThread != 0);
}
int
stopTicker(void)
{
- if (hStopEvent != INVALID_HANDLE_VALUE) {
- SetEvent(hStopEvent);
- }
- return 0;
+ // 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
+ // cannot be allowed to return to a missing DLL.
+
+ if (hStopEvent != INVALID_HANDLE_VALUE &&
+ tickThread != INVALID_HANDLE_VALUE) {
+ DWORD exitCode;
+ SetEvent(hStopEvent);
+ while (1) {
+ WaitForSingleObject(tickThread, 20);
+ if (!GetExitCodeThread(tickThread, &exitCode)) {
+ return 1;
+ }
+ if (exitCode != STILL_ACTIVE) {
+ tickThread = INVALID_HANDLE_VALUE;
+ return 0;
+ }
+ TerminateThread(tickThread, 0);
+ }
+ }
+ return 0;
}