FreeRDP
Loading...
Searching...
No Matches
TestMessageQueue.c
1
2#include <winpr/crt.h>
3#include <winpr/thread.h>
4#include <winpr/collections.h>
5
6static DWORD WINAPI message_queue_consumer_thread(LPVOID arg)
7{
8 wMessage message = WINPR_C_ARRAY_INIT;
9 wMessageQueue* queue = (wMessageQueue*)arg;
10
11 while (MessageQueue_Wait(queue))
12 {
13 if (MessageQueue_Peek(queue, &message, TRUE))
14 {
15 if (message.id == WMQ_QUIT)
16 break;
17
18 printf("Message.Type: %" PRIu32 "\n", message.id);
19 }
20 }
21
22 return 0;
23}
24
25static bool wrap_test(bool (*fkt)(wMessageQueue* queue))
26{
27 wMessageQueue* queue = MessageQueue_New(nullptr);
28 if (!queue)
29 return false;
30
31 WINPR_ASSERT(fkt);
32 const bool rc = fkt(queue);
33 MessageQueue_Free(queue);
34 return rc;
35}
36
37static bool check(const wMessage* message, size_t pos)
38{
39 if (!message)
40 return false;
41 if (message->context != (void*)13)
42 return false;
43 if (message->id != pos)
44 return false;
45 if (message->wParam != (void*)23)
46 return false;
47 if (message->lParam != (void*)42)
48 return false;
49 if (message->Free != nullptr)
50 return false;
51 return true;
52}
53
54static bool append(wMessageQueue* queue, size_t pos)
55{
56 const wMessage message = { .context = (void*)13,
57 .id = WINPR_ASSERTING_INT_CAST(DWORD, pos),
58 .wParam = (void*)23,
59 .lParam = (void*)42,
60 .Free = nullptr };
61
62 return MessageQueue_Dispatch(queue, &message);
63}
64
65static bool fill_capcity(wMessageQueue* queue, size_t* pos)
66{
67 WINPR_ASSERT(pos);
68
69 size_t cpos = *pos;
70 const size_t capacity = MessageQueue_Capacity(queue);
71 while (MessageQueue_Size(queue) < capacity)
72 {
73 if (!append(queue, cpos++))
74 return false;
75 }
76 *pos = cpos;
77 return true;
78}
79
80static bool drain(wMessageQueue* queue, size_t expect)
81{
82 wMessage message = WINPR_C_ARRAY_INIT;
83 if (MessageQueue_Get(queue, &message) < 0)
84 return false;
85 if (!check(&message, expect))
86 return false;
87 return true;
88}
89
90static bool drain_capcity(wMessageQueue* queue, size_t remain, size_t* pos)
91{
92 WINPR_ASSERT(pos);
93
94 size_t cpos = *pos;
95 while (MessageQueue_Size(queue) > remain)
96 {
97 if (!drain(queue, cpos++))
98 return false;
99 }
100 *pos = cpos;
101
102 return true;
103}
104
105static bool test_growth_move(wMessageQueue* queue, bool big)
106{
107 WINPR_ASSERT(queue);
108
109 const size_t cap = MessageQueue_Capacity(queue);
110 if (cap < 4)
111 return false;
112
113 size_t wpos = 0;
114 size_t rpos = 0;
115 if (!fill_capcity(queue, &wpos))
116 return false;
117
118 if (big)
119 {
120 if (!append(queue, wpos++))
121 return false;
122 }
123
124 if (!drain_capcity(queue, 3, &rpos))
125 return false;
126
127 if (!fill_capcity(queue, &wpos))
128 return false;
129
130 if (!append(queue, wpos++))
131 return false;
132
133 return drain_capcity(queue, 0, &rpos);
134}
135
136static bool test_growth_big_move(wMessageQueue* queue)
137{
138 return test_growth_move(queue, true);
139}
140
141static bool test_growth_small_move(wMessageQueue* queue)
142{
143 return test_growth_move(queue, false);
144}
145
146static bool test_operation_run(wMessageQueue* queue, HANDLE thread)
147{
148 WINPR_ASSERT(queue);
149 WINPR_ASSERT(thread);
150
151 if (!MessageQueue_Post(queue, nullptr, 123, nullptr, nullptr))
152 return false;
153
154 if (!MessageQueue_Post(queue, nullptr, 456, nullptr, nullptr))
155 return false;
156
157 if (!MessageQueue_Post(queue, nullptr, 789, nullptr, nullptr))
158 return false;
159
160 if (!MessageQueue_PostQuit(queue, 0))
161 return false;
162
163 const DWORD status = WaitForSingleObject(thread, INFINITE);
164 return (status == WAIT_OBJECT_0);
165}
166
167static bool test_operation(wMessageQueue* queue)
168{
169 WINPR_ASSERT(queue);
170
171 HANDLE thread = CreateThread(nullptr, 0, message_queue_consumer_thread, queue, 0, nullptr);
172 if (!thread)
173 {
174 printf("failed to create thread\n");
175 return false;
176 }
177 const bool rc = test_operation_run(queue, thread);
178 if (!CloseHandle(thread))
179 return false;
180 return rc;
181}
182
183int TestMessageQueue(WINPR_ATTR_UNUSED int argc, WINPR_ATTR_UNUSED char* argv[])
184{
185 if (!wrap_test(test_growth_big_move))
186 return -1;
187 if (!wrap_test(test_growth_small_move))
188 return -2;
189 if (!wrap_test(test_operation))
190 return -3;
191 return 0;
192}