3#include <winpr/sysinfo.h>
5#include <winpr/synch.h>
18 HANDLE CompletionEvent;
20typedef struct apc_data APC_DATA;
22static VOID CALLBACK TimerRoutine(PVOID lpParam, BOOLEAN TimerOrWaitFired)
24 WINPR_UNUSED(TimerOrWaitFired);
29 APC_DATA* apcData = (APC_DATA*)lpParam;
30 const UINT32 CurrentTime = GetTickCount();
31 const INT64 TimerTime = 1ll * CurrentTime - apcData->StartTime;
32 const INT64 expectedTime =
33 1ll * apcData->DueTime + (1ll * apcData->Period * apcData->FireCount);
37 printf(
"TimerRoutine: TimerId: %" PRIu32
" FireCount: %" PRIu32
" ActualTime: %" PRId64
38 " ExpectedTime: %" PRId64
" Discrepancy: %" PRId64
"\n",
39 apcData->TimerId, apcData->FireCount, TimerTime, expectedTime, TimerTime - expectedTime);
43 if (apcData->FireCount == apcData->MaxFireCount)
45 (void)SetEvent(apcData->CompletionEvent);
49int TestSynchTimerQueue(
int argc,
char* argv[])
51 HANDLE hTimers[TIMER_COUNT] = { 0 };
52 APC_DATA apcData[TIMER_COUNT] = { 0 };
57 HANDLE hTimerQueue = CreateTimerQueue();
61 printf(
"CreateTimerQueue failed (%" PRIu32
")\n", GetLastError());
65 for (DWORD index = 0; index < TIMER_COUNT; index++)
67 apcData[index].TimerId = index;
68 apcData[index].StartTime = GetTickCount();
69 apcData[index].DueTime = (index * 10) + 50;
70 apcData[index].Period = 100;
71 apcData[index].FireCount = 0;
72 apcData[index].MaxFireCount = FIRE_COUNT;
74 if (!(apcData[index].CompletionEvent = CreateEvent(NULL, TRUE, FALSE, NULL)))
76 printf(
"Failed to create apcData[%" PRIu32
"] event (%" PRIu32
")\n", index,
81 if (!CreateTimerQueueTimer(&hTimers[index], hTimerQueue, TimerRoutine, &apcData[index],
82 apcData[index].DueTime, apcData[index].Period, 0))
84 printf(
"CreateTimerQueueTimer failed (%" PRIu32
")\n", GetLastError());
89 for (DWORD index = 0; index < TIMER_COUNT; index++)
91 if (WaitForSingleObject(apcData[index].CompletionEvent, 2000) != WAIT_OBJECT_0)
93 printf(
"Failed to wait for timer queue timer #%" PRIu32
" (%" PRIu32
")\n", index,
99 for (DWORD index = 0; index < TIMER_COUNT; index++)
105 if (!DeleteTimerQueueTimer(hTimerQueue, hTimers[index], INVALID_HANDLE_VALUE))
107 printf(
"DeleteTimerQueueTimer failed (%" PRIu32
")\n", GetLastError());
110 (void)CloseHandle(apcData[index].CompletionEvent);
113 if (!DeleteTimerQueue(hTimerQueue))
115 printf(
"DeleteTimerQueue failed (%" PRIu32
")\n", GetLastError());