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)
48 /* interpret a < 0 timeout period as 'instantaneous' */
52 waitRes = WaitForSingleObject(hStopEvent, ms);
56 /* event has become signalled */
58 CloseHandle(hStopEvent);
65 DWORD dw = GetLastError();
66 fprintf(stderr, "TimerProc: wait failed -- error code: %lu\n", dw); fflush(stderr);
70 fprintf(stderr, "TimerProc: unexpected result %lu\n", waitRes); fflush(stderr);
79 startTicker(nat ms, TickProc handle_tick)
82 /* 'hStopEvent' is a manual-reset event that's signalled upon
83 * shutdown of timer service (=> timer thread.)
85 hStopEvent = CreateEvent ( NULL,
89 if (hStopEvent == INVALID_HANDLE_VALUE) {
92 tickProc = handle_tick;
93 tickThread = (HANDLE)(long)_beginthreadex( NULL,
99 return (tickThread != 0);
105 // We must wait for the ticker thread to terminate, since if we
106 // are in a DLL that is about to be unloaded, the ticker thread
107 // cannot be allowed to return to a missing DLL.
109 if (hStopEvent != INVALID_HANDLE_VALUE &&
110 tickThread != INVALID_HANDLE_VALUE) {
112 SetEvent(hStopEvent);
114 WaitForSingleObject(tickThread, 20);
115 if (!GetExitCodeThread(tickThread, &exitCode)) {
118 if (exitCode != STILL_ACTIVE) {
119 tickThread = INVALID_HANDLE_VALUE;
122 TerminateThread(tickThread, 0);