5 #include <winpr/crypto.h>
6 #include <winpr/synch.h>
7 #include <winpr/thread.h>
11 static UINT32 prand(UINT32 max)
16 winpr_RAND(&tmp,
sizeof(tmp));
17 return tmp % (max - 1) + 1;
20 static DWORD WINAPI test_thread(LPVOID arg)
22 UINT32 timeout = 50 + prand(100);
29 static int start_threads(
size_t count, HANDLE* threads)
31 for (
size_t i = 0; i < count; i++)
33 threads[i] = CreateThread(NULL, 0, test_thread, NULL, CREATE_SUSPENDED, NULL);
37 (void)fprintf(stderr,
"%s: CreateThread [%" PRIuz
"] failure\n", __func__, i);
42 for (
size_t i = 0; i < count; i++)
43 ResumeThread(threads[i]);
47 static int close_threads(DWORD count, HANDLE* threads)
51 for (DWORD i = 0; i < count; i++)
56 if (!CloseHandle(threads[i]))
58 (void)fprintf(stderr,
"%s: CloseHandle [%" PRIu32
"] failure\n", __func__, i);
67 static BOOL TestWaitForAll(
void)
70 HANDLE threads[THREADS] = { 0 };
72 if (start_threads(ARRAYSIZE(threads), threads))
74 (void)fprintf(stderr,
"%s: start_threads failed\n", __func__);
78 const DWORD ret = WaitForMultipleObjects(ARRAYSIZE(threads), threads, TRUE, 10);
79 if (ret != WAIT_TIMEOUT)
81 (void)fprintf(stderr,
"%s: WaitForMultipleObjects bWaitAll, timeout 10 failed, ret=%d\n",
86 if (WaitForMultipleObjects(ARRAYSIZE(threads), threads, TRUE, INFINITE) != WAIT_OBJECT_0)
88 (void)fprintf(stderr,
"%s: WaitForMultipleObjects bWaitAll, INFINITE failed\n", __func__);
94 if (close_threads(ARRAYSIZE(threads), threads))
96 (void)fprintf(stderr,
"%s: close_threads failed\n", __func__);
103 static BOOL TestWaitOne(
void)
106 HANDLE threads[THREADS] = { 0 };
108 if (start_threads(ARRAYSIZE(threads), threads))
110 (void)fprintf(stderr,
"%s: start_threads failed\n", __func__);
114 const DWORD ret = WaitForMultipleObjects(ARRAYSIZE(threads), threads, FALSE, INFINITE);
115 if (ret > (WAIT_OBJECT_0 + ARRAYSIZE(threads)))
117 (void)fprintf(stderr,
"%s: WaitForMultipleObjects INFINITE failed\n", __func__);
121 if (WaitForMultipleObjects(ARRAYSIZE(threads), threads, TRUE, INFINITE) != WAIT_OBJECT_0)
123 (void)fprintf(stderr,
"%s: WaitForMultipleObjects bWaitAll, INFINITE failed\n", __func__);
129 if (close_threads(ARRAYSIZE(threads), threads))
131 (void)fprintf(stderr,
"%s: close_threads failed\n", __func__);
138 static BOOL TestWaitOneTimeout(
void)
141 HANDLE threads[THREADS] = { 0 };
143 if (start_threads(ARRAYSIZE(threads), threads))
145 (void)fprintf(stderr,
"%s: start_threads failed\n", __func__);
149 const DWORD ret = WaitForMultipleObjects(ARRAYSIZE(threads), threads, FALSE, 1);
150 if (ret != WAIT_TIMEOUT)
152 (void)fprintf(stderr,
"%s: WaitForMultipleObjects timeout 50 failed, ret=%d\n", __func__,
157 if (WaitForMultipleObjects(ARRAYSIZE(threads), threads, TRUE, INFINITE) != WAIT_OBJECT_0)
159 (void)fprintf(stderr,
"%s: WaitForMultipleObjects bWaitAll, INFINITE failed\n", __func__);
164 if (close_threads(ARRAYSIZE(threads), threads))
166 (void)fprintf(stderr,
"%s: close_threads failed\n", __func__);
173 static BOOL TestWaitOneTimeoutMultijoin(
void)
176 HANDLE threads[THREADS] = { 0 };
178 if (start_threads(ARRAYSIZE(threads), threads))
180 (void)fprintf(stderr,
"%s: start_threads failed\n", __func__);
184 for (
size_t i = 0; i < ARRAYSIZE(threads); i++)
186 const DWORD ret = WaitForMultipleObjects(ARRAYSIZE(threads), threads, FALSE, 0);
187 if (ret != WAIT_TIMEOUT)
189 (void)fprintf(stderr,
"%s: WaitForMultipleObjects timeout 0 failed, ret=%d\n", __func__,
195 if (WaitForMultipleObjects(ARRAYSIZE(threads), threads, TRUE, INFINITE) != WAIT_OBJECT_0)
197 (void)fprintf(stderr,
"%s: WaitForMultipleObjects bWaitAll, INFINITE failed\n", __func__);
203 if (close_threads(ARRAYSIZE(threads), threads))
205 (void)fprintf(stderr,
"%s: close_threads failed\n", __func__);
212 static BOOL TestDetach(
void)
215 HANDLE threads[THREADS] = { 0 };
217 if (start_threads(ARRAYSIZE(threads), threads))
219 (void)fprintf(stderr,
"%s: start_threads failed\n", __func__);
225 if (close_threads(ARRAYSIZE(threads), threads))
227 (void)fprintf(stderr,
"%s: close_threads failed\n", __func__);
234 int TestSynchMultipleThreads(
int argc,
char* argv[])
239 if (!TestWaitForAll())
245 if (!TestWaitOneTimeout())
248 if (!TestWaitOneTimeoutMultijoin())