From bb7b45dcf16118fb03bf28aea08a168ac6598a33 Mon Sep 17 00:00:00 2001 From: Simon Marlow Date: Wed, 27 Jan 2010 13:54:30 +0000 Subject: [PATCH] Don't Terminate the ticker thread (#3748) --- rts/RtsStartup.c | 2 +- rts/Ticker.h | 2 +- rts/Timer.c | 4 ++-- rts/Timer.h | 2 +- rts/posix/Itimer.c | 2 +- rts/win32/Ticker.c | 21 +++++++++++++++------ 6 files changed, 21 insertions(+), 12 deletions(-) diff --git a/rts/RtsStartup.c b/rts/RtsStartup.c index f0b2598..8e2eac4 100644 --- a/rts/RtsStartup.c +++ b/rts/RtsStartup.c @@ -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) diff --git a/rts/Ticker.h b/rts/Ticker.h index 3e62622..37c2696 100644 --- a/rts/Ticker.h +++ b/rts/Ticker.h @@ -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 diff --git a/rts/Timer.c b/rts/Timer.c index 8c178a0..a5d42fb 100644 --- a/rts/Timer.c +++ b/rts/Timer.c @@ -114,9 +114,9 @@ stopTimer(void) } void -exitTimer(void) +exitTimer (rtsBool wait) { if (RtsFlags.MiscFlags.tickInterval != 0) { - exitTicker(); + exitTicker(wait); } } diff --git a/rts/Timer.h b/rts/Timer.h index f0b5459..b03ef06 100644 --- a/rts/Timer.h +++ b/rts/Timer.h @@ -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 */ diff --git a/rts/posix/Itimer.c b/rts/posix/Itimer.c index 3a09e80..2dbf32d 100644 --- a/rts/posix/Itimer.c +++ b/rts/posix/Itimer.c @@ -221,7 +221,7 @@ stopTicker(void) } void -exitTicker(void) +exitTicker (rtsBool wait STG_UNUSED) { #if defined(USE_TIMER_CREATE) timer_delete(timer); diff --git a/rts/win32/Ticker.c b/rts/win32/Ticker.c index 6be1b3a..929e6f4 100644 --- a/rts/win32/Ticker.c +++ b/rts/win32/Ticker.c @@ -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); } } } -- 1.7.10.4