11 #include "OSThreads.h"
14 * Provide a timer service for the RTS, periodically
15 * notifying it that a number of 'ticks' has passed.
19 /* To signal shutdown of the timer service, we use a local
20 * event which the timer thread listens to (and stopVirtTimer()
23 static HANDLE hStopEvent = INVALID_HANDLE_VALUE;
24 static HANDLE tickThread = INVALID_HANDLE_VALUE;
26 static TickProc tickProc = NULL;
29 * Ticking is done by a separate thread which periodically
30 * wakes up to handle a tick.
32 * This is the portable way of providing a timer service under
33 * Win32; features like waitable timers or timer queues are only
34 * supported by a subset of the Win32 platforms (notably not
41 TimerProc(PVOID param)
46 /* interpret a < 0 timeout period as 'instantaneous' */
50 waitRes = WaitForSingleObject(hStopEvent, ms);
54 /* event has become signalled */
56 CloseHandle(hStopEvent);
57 hStopEvent = INVALID_HANDLE_VALUE;
64 DWORD dw = GetLastError();
65 fprintf(stderr, "TimerProc: wait failed -- error code: %lu\n", dw); fflush(stderr);
69 fprintf(stderr, "TimerProc: unexpected result %lu\n", waitRes); fflush(stderr);
78 startTicker(nat ms, TickProc handle_tick)
81 /* 'hStopEvent' is a manual-reset event that's signalled upon
82 * shutdown of timer service (=> timer thread.)
84 hStopEvent = CreateEvent ( NULL,
88 if (hStopEvent == INVALID_HANDLE_VALUE) {
91 tickProc = handle_tick;
92 tickThread = (HANDLE)(long)_beginthreadex( NULL,
98 return (tickThread != 0);
104 // We must wait for the ticker thread to terminate, since if we
105 // are in a DLL that is about to be unloaded, the ticker thread
106 // cannot be allowed to return to a missing DLL.
108 if (hStopEvent != INVALID_HANDLE_VALUE &&
109 tickThread != INVALID_HANDLE_VALUE) {
111 SetEvent(hStopEvent);
113 WaitForSingleObject(tickThread, 20);
114 if (!GetExitCodeThread(tickThread, &exitCode)) {
117 if (exitCode != STILL_ACTIVE) {
118 tickThread = INVALID_HANDLE_VALUE;
119 if ( hStopEvent != INVALID_HANDLE_VALUE ) {
120 CloseHandle(hStopEvent);
121 hStopEvent = INVALID_HANDLE_VALUE;
125 TerminateThread(tickThread, 0);