FreeRDP
Loading...
Searching...
No Matches
TestSynchTimerQueue.c
1
2#include <winpr/crt.h>
3#include <winpr/sysinfo.h>
4#include <winpr/file.h>
5#include <winpr/synch.h>
6
7#define FIRE_COUNT 5
8#define TIMER_COUNT 5
9
10struct apc_data
11{
12 DWORD TimerId;
13 DWORD FireCount;
14 DWORD DueTime;
15 DWORD Period;
16 UINT32 StartTime;
17 DWORD MaxFireCount;
18 HANDLE CompletionEvent;
19};
20typedef struct apc_data APC_DATA;
21
22static VOID CALLBACK TimerRoutine(PVOID lpParam, BOOLEAN TimerOrWaitFired)
23{
24 WINPR_UNUSED(TimerOrWaitFired);
25
26 if (!lpParam)
27 return;
28
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);
34
35 apcData->FireCount++;
36
37 printf("TimerRoutine: TimerId: %" PRIu32 " FireCount: %" PRIu32 " ActualTime: %" PRId64
38 " ExpectedTime: %" PRId64 " Discrepancy: %" PRId64 "\n",
39 apcData->TimerId, apcData->FireCount, TimerTime, expectedTime, TimerTime - expectedTime);
40
41 Sleep(11);
42
43 if (apcData->FireCount == apcData->MaxFireCount)
44 {
45 (void)SetEvent(apcData->CompletionEvent);
46 }
47}
48
49int TestSynchTimerQueue(int argc, char* argv[])
50{
51 HANDLE hTimers[TIMER_COUNT] = { 0 };
52 APC_DATA apcData[TIMER_COUNT] = { 0 };
53
54 WINPR_UNUSED(argc);
55 WINPR_UNUSED(argv);
56
57 HANDLE hTimerQueue = CreateTimerQueue();
58
59 if (!hTimerQueue)
60 {
61 printf("CreateTimerQueue failed (%" PRIu32 ")\n", GetLastError());
62 return -1;
63 }
64
65 for (DWORD index = 0; index < TIMER_COUNT; index++)
66 {
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;
73
74 if (!(apcData[index].CompletionEvent = CreateEvent(NULL, TRUE, FALSE, NULL)))
75 {
76 printf("Failed to create apcData[%" PRIu32 "] event (%" PRIu32 ")\n", index,
77 GetLastError());
78 return -1;
79 }
80
81 if (!CreateTimerQueueTimer(&hTimers[index], hTimerQueue, TimerRoutine, &apcData[index],
82 apcData[index].DueTime, apcData[index].Period, 0))
83 {
84 printf("CreateTimerQueueTimer failed (%" PRIu32 ")\n", GetLastError());
85 return -1;
86 }
87 }
88
89 for (DWORD index = 0; index < TIMER_COUNT; index++)
90 {
91 if (WaitForSingleObject(apcData[index].CompletionEvent, 2000) != WAIT_OBJECT_0)
92 {
93 printf("Failed to wait for timer queue timer #%" PRIu32 " (%" PRIu32 ")\n", index,
94 GetLastError());
95 return -1;
96 }
97 }
98
99 for (DWORD index = 0; index < TIMER_COUNT; index++)
100 {
105 if (!DeleteTimerQueueTimer(hTimerQueue, hTimers[index], INVALID_HANDLE_VALUE))
106 {
107 printf("DeleteTimerQueueTimer failed (%" PRIu32 ")\n", GetLastError());
108 return -1;
109 }
110 (void)CloseHandle(apcData[index].CompletionEvent);
111 }
112
113 if (!DeleteTimerQueue(hTimerQueue))
114 {
115 printf("DeleteTimerQueue failed (%" PRIu32 ")\n", GetLastError());
116 return -1;
117 }
118
119 return 0;
120}