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 UINT32 TimerTime = 0;
25 APC_DATA* apcData = NULL;
26 UINT32 expectedTime = 0;
27 UINT32 CurrentTime = GetTickCount();
28
29 WINPR_UNUSED(TimerOrWaitFired);
30
31 if (!lpParam)
32 return;
33
34 apcData = (APC_DATA*)lpParam;
35
36 TimerTime = CurrentTime - apcData->StartTime;
37 expectedTime = apcData->DueTime + (apcData->Period * apcData->FireCount);
38
39 apcData->FireCount++;
40
41 printf("TimerRoutine: TimerId: %" PRIu32 " FireCount: %" PRIu32 " ActualTime: %" PRIu32
42 " ExpectedTime: %" PRIu32 " Discrepancy: %" PRIu32 "\n",
43 apcData->TimerId, apcData->FireCount, TimerTime, expectedTime, TimerTime - expectedTime);
44
45 Sleep(11);
46
47 if (apcData->FireCount == apcData->MaxFireCount)
48 {
49 (void)SetEvent(apcData->CompletionEvent);
50 }
51}
52
53int TestSynchTimerQueue(int argc, char* argv[])
54{
55 HANDLE hTimerQueue = NULL;
56 HANDLE hTimers[TIMER_COUNT];
57 APC_DATA apcData[TIMER_COUNT];
58
59 WINPR_UNUSED(argc);
60 WINPR_UNUSED(argv);
61
62 hTimerQueue = CreateTimerQueue();
63
64 if (!hTimerQueue)
65 {
66 printf("CreateTimerQueue failed (%" PRIu32 ")\n", GetLastError());
67 return -1;
68 }
69
70 for (DWORD index = 0; index < TIMER_COUNT; index++)
71 {
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;
78
79 if (!(apcData[index].CompletionEvent = CreateEvent(NULL, TRUE, FALSE, NULL)))
80 {
81 printf("Failed to create apcData[%" PRIu32 "] event (%" PRIu32 ")\n", index,
82 GetLastError());
83 return -1;
84 }
85
86 if (!CreateTimerQueueTimer(&hTimers[index], hTimerQueue, TimerRoutine, &apcData[index],
87 apcData[index].DueTime, apcData[index].Period, 0))
88 {
89 printf("CreateTimerQueueTimer failed (%" PRIu32 ")\n", GetLastError());
90 return -1;
91 }
92 }
93
94 for (DWORD index = 0; index < TIMER_COUNT; index++)
95 {
96 if (WaitForSingleObject(apcData[index].CompletionEvent, 2000) != WAIT_OBJECT_0)
97 {
98 printf("Failed to wait for timer queue timer #%" PRIu32 " (%" PRIu32 ")\n", index,
99 GetLastError());
100 return -1;
101 }
102 }
103
104 for (DWORD index = 0; index < TIMER_COUNT; index++)
105 {
110 if (!DeleteTimerQueueTimer(hTimerQueue, hTimers[index], INVALID_HANDLE_VALUE))
111 {
112 printf("DeleteTimerQueueTimer failed (%" PRIu32 ")\n", GetLastError());
113 return -1;
114 }
115 (void)CloseHandle(apcData[index].CompletionEvent);
116 }
117
118 if (!DeleteTimerQueue(hTimerQueue))
119 {
120 printf("DeleteTimerQueue failed (%" PRIu32 ")\n", GetLastError());
121 return -1;
122 }
123
124 return 0;
125}