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);
63 DWORD dw = GetLastError();
64 fprintf(stderr, "TimerProc: wait failed -- error code: %lu\n", dw); fflush(stderr);
68 fprintf(stderr, "TimerProc: unexpected result %lu\n", waitRes); fflush(stderr);
77 startTicker(nat ms, TickProc handle_tick)
80 /* 'hStopEvent' is a manual-reset event that's signalled upon
81 * shutdown of timer service (=> timer thread.)
83 hStopEvent = CreateEvent ( NULL,
87 if (hStopEvent == INVALID_HANDLE_VALUE) {
90 tickProc = handle_tick;
91 tickThread = (HANDLE)(long)_beginthreadex( NULL,
97 return (tickThread != 0);
103 // We must wait for the ticker thread to terminate, since if we
104 // are in a DLL that is about to be unloaded, the ticker thread
105 // cannot be allowed to return to a missing DLL.
107 if (hStopEvent != INVALID_HANDLE_VALUE &&
108 tickThread != INVALID_HANDLE_VALUE) {
110 SetEvent(hStopEvent);
112 WaitForSingleObject(tickThread, 20);
113 if (!GetExitCodeThread(tickThread, &exitCode)) {
116 if (exitCode != STILL_ACTIVE) {
117 tickThread = INVALID_HANDLE_VALUE;
118 CloseHandle(hStopEvent);
121 TerminateThread(tickThread, 0);