3 #include <winpr/sysinfo.h>
4 #include <winpr/file.h>
5 #include <winpr/synch.h>
18 HANDLE CompletionEvent;
20 typedef struct apc_data APC_DATA;
22 static VOID CALLBACK TimerRoutine(PVOID lpParam, BOOLEAN TimerOrWaitFired)
25 APC_DATA* apcData = NULL;
26 UINT32 expectedTime = 0;
27 UINT32 CurrentTime = GetTickCount();
29 WINPR_UNUSED(TimerOrWaitFired);
34 apcData = (APC_DATA*)lpParam;
36 TimerTime = CurrentTime - apcData->StartTime;
37 expectedTime = apcData->DueTime + (apcData->Period * apcData->FireCount);
41 printf(
"TimerRoutine: TimerId: %" PRIu32
" FireCount: %" PRIu32
" ActualTime: %" PRIu32
42 " ExpectedTime: %" PRIu32
" Discrepancy: %" PRIu32
"\n",
43 apcData->TimerId, apcData->FireCount, TimerTime, expectedTime, TimerTime - expectedTime);
47 if (apcData->FireCount == apcData->MaxFireCount)
49 (void)SetEvent(apcData->CompletionEvent);
53 int TestSynchTimerQueue(
int argc,
char* argv[])
55 HANDLE hTimerQueue = NULL;
56 HANDLE hTimers[TIMER_COUNT];
57 APC_DATA apcData[TIMER_COUNT];
62 hTimerQueue = CreateTimerQueue();
66 printf(
"CreateTimerQueue failed (%" PRIu32
")\n", GetLastError());
70 for (DWORD index = 0; index < TIMER_COUNT; index++)
72 apcData[index].TimerId = index;
73 apcData[index].StartTime = GetTickCount();
74 apcData[index].DueTime = (index * 10) + 50;
75 apcData[index].Period = 100;
76 apcData[index].FireCount = 0;
77 apcData[index].MaxFireCount = FIRE_COUNT;
79 if (!(apcData[index].CompletionEvent = CreateEvent(NULL, TRUE, FALSE, NULL)))
81 printf(
"Failed to create apcData[%" PRIu32
"] event (%" PRIu32
")\n", index,
86 if (!CreateTimerQueueTimer(&hTimers[index], hTimerQueue, TimerRoutine, &apcData[index],
87 apcData[index].DueTime, apcData[index].Period, 0))
89 printf(
"CreateTimerQueueTimer failed (%" PRIu32
")\n", GetLastError());
94 for (DWORD index = 0; index < TIMER_COUNT; index++)
96 if (WaitForSingleObject(apcData[index].CompletionEvent, 2000) != WAIT_OBJECT_0)
98 printf(
"Failed to wait for timer queue timer #%" PRIu32
" (%" PRIu32
")\n", index,
104 for (DWORD index = 0; index < TIMER_COUNT; index++)
110 if (!DeleteTimerQueueTimer(hTimerQueue, hTimers[index], INVALID_HANDLE_VALUE))
112 printf(
"DeleteTimerQueueTimer failed (%" PRIu32
")\n", GetLastError());
115 (void)CloseHandle(apcData[index].CompletionEvent);
118 if (!DeleteTimerQueue(hTimerQueue))
120 printf(
"DeleteTimerQueue failed (%" PRIu32
")\n", GetLastError());