Git conversion: Make reactos the root directory, move rosapps, rostests, wallpapers...
[reactos.git] / modules / rostests / winetests / kernel32 / sync.c
1 /*
2 * Synchronization tests
3 *
4 * Copyright 2005 Mike McCormack for CodeWeavers
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 */
20
21 //#define _WIN32_WINNT 0x500
22 #include <stdarg.h>
23 #include <stdlib.h>
24 #include <stdio.h>
25 #include <windef.h>
26 #include <winbase.h>
27 #include <wine/winternl.h>
28
29 #include <wine/test.h>
30
31 #define QueryDepthSList(x) RtlQueryDepthSList(x)
32 #define InterlockedPushEntrySList(x,y) RtlInterlockedPushEntrySList(x,y)
33 #define InterlockedPopEntrySList(x) RtlInterlockedPopEntrySList(x)
34 #define InterlockedFlushSList(x) RtlInterlockedFlushSList(x)
35
36 #undef __fastcall
37 #define __fastcall __stdcall
38
39 static BOOL (WINAPI *pChangeTimerQueueTimer)(HANDLE, HANDLE, ULONG, ULONG);
40 static HANDLE (WINAPI *pCreateTimerQueue)(void);
41 static BOOL (WINAPI *pCreateTimerQueueTimer)(PHANDLE, HANDLE, WAITORTIMERCALLBACK,
42 PVOID, DWORD, DWORD, ULONG);
43 static HANDLE (WINAPI *pCreateWaitableTimerA)(SECURITY_ATTRIBUTES*,BOOL,LPCSTR);
44 static BOOL (WINAPI *pDeleteTimerQueueEx)(HANDLE, HANDLE);
45 static BOOL (WINAPI *pDeleteTimerQueueTimer)(HANDLE, HANDLE, HANDLE);
46 static HANDLE (WINAPI *pOpenWaitableTimerA)(DWORD,BOOL,LPCSTR);
47 static HANDLE (WINAPI *pCreateMemoryResourceNotification)(MEMORY_RESOURCE_NOTIFICATION_TYPE);
48 static BOOL (WINAPI *pQueryMemoryResourceNotification)(HANDLE, PBOOL);
49 static VOID (WINAPI *pInitOnceInitialize)(PINIT_ONCE);
50 static BOOL (WINAPI *pInitOnceExecuteOnce)(PINIT_ONCE,PINIT_ONCE_FN,PVOID,LPVOID*);
51 static BOOL (WINAPI *pInitOnceBeginInitialize)(PINIT_ONCE,DWORD,BOOL*,LPVOID*);
52 static BOOL (WINAPI *pInitOnceComplete)(PINIT_ONCE,DWORD,LPVOID);
53
54 static VOID (WINAPI *pInitializeConditionVariable)(PCONDITION_VARIABLE);
55 static BOOL (WINAPI *pSleepConditionVariableCS)(PCONDITION_VARIABLE,PCRITICAL_SECTION,DWORD);
56 static BOOL (WINAPI *pSleepConditionVariableSRW)(PCONDITION_VARIABLE,PSRWLOCK,DWORD,ULONG);
57 static VOID (WINAPI *pWakeAllConditionVariable)(PCONDITION_VARIABLE);
58 static VOID (WINAPI *pWakeConditionVariable)(PCONDITION_VARIABLE);
59
60 static VOID (WINAPI *pInitializeSRWLock)(PSRWLOCK);
61 static VOID (WINAPI *pAcquireSRWLockExclusive)(PSRWLOCK);
62 static VOID (WINAPI *pAcquireSRWLockShared)(PSRWLOCK);
63 static VOID (WINAPI *pReleaseSRWLockExclusive)(PSRWLOCK);
64 static VOID (WINAPI *pReleaseSRWLockShared)(PSRWLOCK);
65 static BOOLEAN (WINAPI *pTryAcquireSRWLockExclusive)(PSRWLOCK);
66 static BOOLEAN (WINAPI *pTryAcquireSRWLockShared)(PSRWLOCK);
67
68 static NTSTATUS (WINAPI *pNtAllocateVirtualMemory)(HANDLE, PVOID *, ULONG, SIZE_T *, ULONG, ULONG);
69 static NTSTATUS (WINAPI *pNtFreeVirtualMemory)(HANDLE, PVOID *, SIZE_T *, ULONG);
70 static NTSTATUS (WINAPI *pNtWaitForSingleObject)(HANDLE, BOOLEAN, const LARGE_INTEGER *);
71 static NTSTATUS (WINAPI *pNtWaitForMultipleObjects)(ULONG,const HANDLE*,BOOLEAN,BOOLEAN,const LARGE_INTEGER*);
72 static PSLIST_ENTRY (__fastcall *pRtlInterlockedPushListSList)(PSLIST_HEADER list, PSLIST_ENTRY first,
73 PSLIST_ENTRY last, ULONG count);
74 static PSLIST_ENTRY (WINAPI *pRtlInterlockedPushListSListEx)(PSLIST_HEADER list, PSLIST_ENTRY first,
75 PSLIST_ENTRY last, ULONG count);
76
77 #ifdef __i386__
78
79 #include "pshpack1.h"
80 struct fastcall_thunk
81 {
82 BYTE pop_edx; /* popl %edx (ret addr) */
83 BYTE pop_eax; /* popl %eax (func) */
84 BYTE pop_ecx; /* popl %ecx (param 1) */
85 BYTE xchg[3]; /* xchgl (%esp),%edx (param 2) */
86 WORD jmp_eax; /* jmp *%eax */
87 };
88 #include "poppack.h"
89
90 static void * (WINAPI *call_fastcall_func4)(void *func, const void *a, const void *b, const void *c, const void *d);
91
92 static void init_fastcall_thunk(void)
93 {
94 struct fastcall_thunk *thunk = VirtualAlloc(NULL, sizeof(*thunk), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
95 thunk->pop_edx = 0x5a; /* popl %edx */
96 thunk->pop_eax = 0x58; /* popl %eax */
97 thunk->pop_ecx = 0x59; /* popl %ecx */
98 thunk->xchg[0] = 0x87; /* xchgl (%esp),%edx */
99 thunk->xchg[1] = 0x14;
100 thunk->xchg[2] = 0x24;
101 thunk->jmp_eax = 0xe0ff; /* jmp *%eax */
102 call_fastcall_func4 = (void *)thunk;
103 }
104
105 #define call_func4(func, a, b, c, d) call_fastcall_func4(func, (const void *)(a), \
106 (const void *)(b), (const void *)(c), (const void *)(d))
107
108 #else /* __i386__ */
109
110 #define init_fastcall_thunk() do { } while(0)
111 #define call_func4(func, a, b, c, d) func(a, b, c, d)
112
113 #endif /* __i386__ */
114
115 static void test_signalandwait(void)
116 {
117 DWORD (WINAPI *pSignalObjectAndWait)(HANDLE, HANDLE, DWORD, BOOL);
118 HMODULE kernel32;
119 DWORD r;
120 HANDLE event[2], semaphore[2], file;
121 int i;
122
123 kernel32 = GetModuleHandleA("kernel32.dll");
124 pSignalObjectAndWait = (void*) GetProcAddress(kernel32, "SignalObjectAndWait");
125
126 if (!pSignalObjectAndWait)
127 return;
128
129 /* invalid parameters */
130 r = pSignalObjectAndWait(NULL, NULL, 0, 0);
131 if (r == ERROR_INVALID_FUNCTION)
132 {
133 win_skip("SignalObjectAndWait is not implemented\n");
134 return; /* Win98/ME */
135 }
136 ok( r == WAIT_FAILED, "should fail\n");
137
138 event[0] = CreateEventW(NULL, 0, 0, NULL);
139 event[1] = CreateEventW(NULL, 1, 1, NULL);
140
141 ok( event[0] && event[1], "failed to create event flags\n");
142
143 r = pSignalObjectAndWait(event[0], NULL, 0, FALSE);
144 ok( r == WAIT_FAILED, "should fail\n");
145
146 r = pSignalObjectAndWait(NULL, event[0], 0, FALSE);
147 ok( r == WAIT_FAILED, "should fail\n");
148
149
150 /* valid parameters */
151 r = pSignalObjectAndWait(event[0], event[1], 0, FALSE);
152 ok( r == WAIT_OBJECT_0, "should succeed\n");
153
154 /* event[0] is now signalled - we repeat this test multiple times
155 * to ensure that the wineserver handles this situation properly. */
156 for (i = 0; i < 10000; i++)
157 {
158 r = pSignalObjectAndWait(event[0], event[0], 0, FALSE);
159 ok(r == WAIT_OBJECT_0, "should succeed\n");
160 }
161
162 /* event[0] is not signalled */
163 r = WaitForSingleObject(event[0], 0);
164 ok( r == WAIT_TIMEOUT, "event was signalled\n");
165
166 r = pSignalObjectAndWait(event[0], event[0], 0, FALSE);
167 ok( r == WAIT_OBJECT_0, "should succeed\n");
168
169 /* clear event[1] and check for a timeout */
170 ok(ResetEvent(event[1]), "failed to clear event[1]\n");
171 r = pSignalObjectAndWait(event[0], event[1], 0, FALSE);
172 ok( r == WAIT_TIMEOUT, "should timeout\n");
173
174 CloseHandle(event[0]);
175 CloseHandle(event[1]);
176
177 /* semaphores */
178 semaphore[0] = CreateSemaphoreW( NULL, 0, 1, NULL );
179 semaphore[1] = CreateSemaphoreW( NULL, 1, 1, NULL );
180 ok( semaphore[0] && semaphore[1], "failed to create semaphore\n");
181
182 r = pSignalObjectAndWait(semaphore[0], semaphore[1], 0, FALSE);
183 ok( r == WAIT_OBJECT_0, "should succeed\n");
184
185 r = pSignalObjectAndWait(semaphore[0], semaphore[1], 0, FALSE);
186 ok( r == WAIT_FAILED, "should fail\n");
187
188 r = ReleaseSemaphore(semaphore[0],1,NULL);
189 ok( r == FALSE, "should fail\n");
190
191 r = ReleaseSemaphore(semaphore[1],1,NULL);
192 ok( r == TRUE, "should succeed\n");
193
194 CloseHandle(semaphore[0]);
195 CloseHandle(semaphore[1]);
196
197 /* try a registry key */
198 file = CreateFileA("x", GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
199 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE, NULL);
200 r = pSignalObjectAndWait(file, file, 0, FALSE);
201 ok( r == WAIT_FAILED, "should fail\n");
202 ok( ERROR_INVALID_HANDLE == GetLastError(), "should return invalid handle error\n");
203 CloseHandle(file);
204 }
205
206 static void test_mutex(void)
207 {
208 DWORD wait_ret;
209 BOOL ret;
210 HANDLE hCreated;
211 HANDLE hOpened;
212 int i;
213 DWORD failed = 0;
214
215 SetLastError(0xdeadbeef);
216 hOpened = OpenMutexA(0, FALSE, "WineTestMutex");
217 ok(hOpened == NULL, "OpenMutex succeeded\n");
218 ok(GetLastError() == ERROR_FILE_NOT_FOUND, "wrong error %u\n", GetLastError());
219
220 SetLastError(0xdeadbeef);
221 hCreated = CreateMutexA(NULL, FALSE, "WineTestMutex");
222 ok(hCreated != NULL, "CreateMutex failed with error %d\n", GetLastError());
223
224 SetLastError(0xdeadbeef);
225 hOpened = OpenMutexA(0, FALSE, "WineTestMutex");
226 todo_wine
227 ok(hOpened == NULL, "OpenMutex succeeded\n");
228 todo_wine
229 ok(GetLastError() == ERROR_ACCESS_DENIED, "wrong error %u\n", GetLastError());
230
231 SetLastError(0xdeadbeef);
232 hOpened = OpenMutexA(GENERIC_EXECUTE, FALSE, "WineTestMutex");
233 ok(hOpened != NULL, "OpenMutex failed with error %d\n", GetLastError());
234 wait_ret = WaitForSingleObject(hOpened, INFINITE);
235 ok(wait_ret == WAIT_OBJECT_0, "WaitForSingleObject failed with error %d\n", GetLastError());
236 CloseHandle(hOpened);
237
238 for(i=0; i < 31; i++)
239 {
240 wait_ret = WaitForSingleObject(hCreated, INFINITE);
241 ok(wait_ret == WAIT_OBJECT_0, "WaitForSingleObject failed with error 0x%08x\n", wait_ret);
242 }
243
244 SetLastError(0xdeadbeef);
245 hOpened = OpenMutexA(GENERIC_READ | GENERIC_WRITE, FALSE, "WineTestMutex");
246 ok(hOpened != NULL, "OpenMutex failed with error %d\n", GetLastError());
247 wait_ret = WaitForSingleObject(hOpened, INFINITE);
248 ok(wait_ret == WAIT_FAILED, "WaitForSingleObject succeeded\n");
249 CloseHandle(hOpened);
250
251 for (i = 0; i < 32; i++)
252 {
253 SetLastError(0xdeadbeef);
254 hOpened = OpenMutexA(0x1 << i, FALSE, "WineTestMutex");
255 if(hOpened != NULL)
256 {
257 SetLastError(0xdeadbeef);
258 ret = ReleaseMutex(hOpened);
259 ok(ret, "ReleaseMutex failed with error %d, access %x\n", GetLastError(), 1 << i);
260 CloseHandle(hOpened);
261 }
262 else
263 {
264 if ((1 << i) == ACCESS_SYSTEM_SECURITY)
265 todo_wine ok(GetLastError() == ERROR_PRIVILEGE_NOT_HELD, "wrong error %u, access %x\n", GetLastError(), 1 << i);
266 else
267 todo_wine ok(GetLastError() == ERROR_ACCESS_DENIED, "wrong error %u, , access %x\n", GetLastError(), 1 << i);
268 ReleaseMutex(hCreated);
269 failed |=0x1 << i;
270 }
271 }
272
273 todo_wine
274 ok( failed == 0x0de0fffe, "open succeeded when it shouldn't: %x\n", failed);
275
276 SetLastError(0xdeadbeef);
277 ret = ReleaseMutex(hCreated);
278 ok(!ret && (GetLastError() == ERROR_NOT_OWNER),
279 "ReleaseMutex should have failed with ERROR_NOT_OWNER instead of %d\n", GetLastError());
280
281 /* test case sensitivity */
282
283 SetLastError(0xdeadbeef);
284 hOpened = OpenMutexA(READ_CONTROL, FALSE, "WINETESTMUTEX");
285 ok(!hOpened, "OpenMutex succeeded\n");
286 ok(GetLastError() == ERROR_FILE_NOT_FOUND, "wrong error %u\n", GetLastError());
287
288 SetLastError(0xdeadbeef);
289 hOpened = OpenMutexA(READ_CONTROL, FALSE, "winetestmutex");
290 ok(!hOpened, "OpenMutex succeeded\n");
291 ok(GetLastError() == ERROR_FILE_NOT_FOUND, "wrong error %u\n", GetLastError());
292
293 SetLastError(0xdeadbeef);
294 hOpened = CreateMutexA(NULL, FALSE, "WineTestMutex");
295 ok(hOpened != NULL, "CreateMutex failed with error %d\n", GetLastError());
296 ok(GetLastError() == ERROR_ALREADY_EXISTS, "wrong error %u\n", GetLastError());
297 CloseHandle(hOpened);
298
299 SetLastError(0xdeadbeef);
300 hOpened = CreateMutexA(NULL, FALSE, "WINETESTMUTEX");
301 ok(hOpened != NULL, "CreateMutex failed with error %d\n", GetLastError());
302 ok(GetLastError() == 0, "wrong error %u\n", GetLastError());
303 CloseHandle(hOpened);
304
305 CloseHandle(hCreated);
306 }
307
308 static void test_slist(void)
309 {
310 struct item
311 {
312 SLIST_ENTRY entry;
313 int value;
314 } item1, item2, item3, *item;
315 SLIST_HEADER slist_header;
316 SLIST_ENTRY *entry;
317 USHORT size;
318 int i;
319
320 item1.value = 1;
321 item2.value = 2;
322 item3.value = 3;
323
324 memset(&slist_header, 0xff, sizeof(slist_header));
325 InitializeSListHead(&slist_header);
326 size = QueryDepthSList(&slist_header);
327 ok(size == 0, "Expected size == 0, got %u\n", size);
328
329 /* test PushEntry, PopEntry and Flush */
330 entry = InterlockedPushEntrySList(&slist_header, &item1.entry);
331 ok(entry == NULL, "Expected entry == NULL, got %p\n", entry);
332 size = QueryDepthSList(&slist_header);
333 ok(size == 1, "Expected size == 1, got %u\n", size);
334
335 entry = InterlockedPushEntrySList(&slist_header, &item2.entry);
336 ok(entry != NULL, "Expected entry != NULL, got %p\n", entry);
337 item = CONTAINING_RECORD(entry, struct item, entry);
338 ok(item->value == 1, "Expected item->value == 1, got %u\n", item->value);
339 size = QueryDepthSList(&slist_header);
340 ok(size == 2, "Expected size == 2, got %u\n", size);
341
342 entry = InterlockedPushEntrySList(&slist_header, &item3.entry);
343 ok(entry != NULL, "Expected entry != NULL, got %p\n", entry);
344 item = CONTAINING_RECORD(entry, struct item, entry);
345 ok(item->value == 2, "Expected item->value == 2, got %u\n", item->value);
346 size = QueryDepthSList(&slist_header);
347 ok(size == 3, "Expected size == 3, got %u\n", size);
348
349 entry = InterlockedPopEntrySList(&slist_header);
350 ok(entry != NULL, "Expected entry != NULL, got %p\n", entry);
351 item = CONTAINING_RECORD(entry, struct item, entry);
352 ok(item->value == 3, "Expected item->value == 3, got %u\n", item->value);
353 size = QueryDepthSList(&slist_header);
354 ok(size == 2, "Expected size == 2, got %u\n", size);
355
356 entry = InterlockedFlushSList(&slist_header);
357 ok(entry != NULL, "Expected entry != NULL, got %p\n", entry);
358 item = CONTAINING_RECORD(entry, struct item, entry);
359 ok(item->value == 2, "Expected item->value == 2, got %u\n", item->value);
360 item = CONTAINING_RECORD(item->entry.Next, struct item, entry);
361 ok(item->value == 1, "Expected item->value == 1, got %u\n", item->value);
362 size = QueryDepthSList(&slist_header);
363 ok(size == 0, "Expected size == 0, got %u\n", size);
364 entry = InterlockedPopEntrySList(&slist_header);
365 ok(entry == NULL, "Expected entry == NULL, got %p\n", entry);
366
367 /* test RtlInterlockedPushListSList */
368 entry = InterlockedPushEntrySList(&slist_header, &item3.entry);
369 ok(entry == NULL, "Expected entry == NULL, got %p\n", entry);
370 entry = call_func4(pRtlInterlockedPushListSList, &slist_header, &item2.entry, &item1.entry, 42);
371 ok(entry != NULL, "Expected entry != NULL, got %p\n", entry);
372 item = CONTAINING_RECORD(entry, struct item, entry);
373 ok(item->value == 3, "Expected item->value == 3, got %u\n", item->value);
374 size = QueryDepthSList(&slist_header);
375 ok(size == 43, "Expected size == 43, got %u\n", size);
376
377 entry = InterlockedPopEntrySList(&slist_header);
378 ok(entry != NULL, "Expected entry != NULL, got %p\n", entry);
379 item = CONTAINING_RECORD(entry, struct item, entry);
380 ok(item->value == 2, "Expected item->value == 2, got %u\n", item->value);
381 size = QueryDepthSList(&slist_header);
382 ok(size == 42, "Expected size == 42, got %u\n", size);
383
384 entry = InterlockedPopEntrySList(&slist_header);
385 ok(entry != NULL, "Expected entry != NULL, got %p\n", entry);
386 item = CONTAINING_RECORD(entry, struct item, entry);
387 ok(item->value == 1, "Expected item->value == 1, got %u\n", item->value);
388 size = QueryDepthSList(&slist_header);
389 ok(size == 41, "Expected size == 41, got %u\n", size);
390
391 entry = InterlockedPopEntrySList(&slist_header);
392 ok(entry != NULL, "Expected entry != NULL, got %p\n", entry);
393 item = CONTAINING_RECORD(entry, struct item, entry);
394 ok(item->value == 3, "Expected item->value == 3, got %u\n", item->value);
395 size = QueryDepthSList(&slist_header);
396 ok(size == 40, "Expected size == 40, got %u\n", size);
397
398 entry = InterlockedPopEntrySList(&slist_header);
399 ok(entry == NULL, "Expected entry == NULL, got %p\n", entry);
400 size = QueryDepthSList(&slist_header);
401 ok(size == 40, "Expected size == 40, got %u\n", size);
402
403 entry = InterlockedFlushSList(&slist_header);
404 ok(entry == NULL, "Expected entry == NULL, got %p\n", entry);
405 size = QueryDepthSList(&slist_header);
406 ok(size == 40 || broken(size == 0) /* >= Win 8 */, "Expected size == 40, got %u\n", size);
407
408 entry = InterlockedPushEntrySList(&slist_header, &item1.entry);
409 ok(entry == NULL, "Expected entry == NULL, got %p\n", entry);
410 entry = InterlockedFlushSList(&slist_header);
411 ok(entry != NULL, "Expected entry != NULL, got %p\n", entry);
412 item = CONTAINING_RECORD(entry, struct item, entry);
413 ok(item->value == 1, "Expected item->value == 1, got %u\n", item->value);
414 size = QueryDepthSList(&slist_header);
415 ok(size == 0, "Expected size == 0, got %u\n", size);
416
417 /* test RtlInterlockedPushListSListEx */
418 if (pRtlInterlockedPushListSListEx)
419 {
420 entry = InterlockedPushEntrySList(&slist_header, &item3.entry);
421 ok(entry == NULL, "Expected entry == NULL, got %p\n", entry);
422 entry = pRtlInterlockedPushListSListEx(&slist_header, &item2.entry, &item1.entry, 42);
423 ok(entry != NULL, "Expected entry != NULL, got %p\n", entry);
424 item = CONTAINING_RECORD(entry, struct item, entry);
425 ok(item->value == 3, "Expected item->value == 3, got %u\n", item->value);
426 size = QueryDepthSList(&slist_header);
427 ok(size == 43, "Expected size == 43, got %u\n", size);
428
429 entry = InterlockedFlushSList(&slist_header);
430 ok(entry != NULL, "Expected entry != NULL, got %p\n", entry);
431 item = CONTAINING_RECORD(entry, struct item, entry);
432 ok(item->value == 2, "Expected item->value == 2, got %u\n", item->value);
433 item = CONTAINING_RECORD(item->entry.Next, struct item, entry);
434 ok(item->value == 1, "Expected item->value == 1, got %u\n", item->value);
435 item = CONTAINING_RECORD(item->entry.Next, struct item, entry);
436 ok(item->value == 3, "Expected item->value == 3, got %u\n", item->value);
437 size = QueryDepthSList(&slist_header);
438 ok(size == 0, "Expected size == 0, got %u\n", size);
439 }
440 else
441 win_skip("RtlInterlockedPushListSListEx not available, skipping tests\n");
442
443 /* test with a lot of items */
444 for (i = 0; i < 65536; i++)
445 {
446 item = HeapAlloc(GetProcessHeap(), 0, sizeof(*item));
447 item->value = i + 1;
448 entry = InterlockedPushEntrySList(&slist_header, &item->entry);
449 if (i)
450 {
451 ok(entry != NULL, "Expected entry != NULL, got %p\n", entry);
452 item = CONTAINING_RECORD(entry, struct item, entry);
453 ok(item->value == i, "Expected item->value == %u, got %u\n", i, item->value);
454 }
455 else
456 {
457 ok(entry == NULL, "Expected entry == NULL, got %p\n", entry);
458 }
459 size = QueryDepthSList(&slist_header);
460 ok(size == ((i + 1) & 0xffff), "Expected size == %u, got %u\n", (i + 1) & 0xffff, size);
461 }
462
463 entry = InterlockedFlushSList(&slist_header);
464 for (i = 65536; i > 0; i--)
465 {
466 ok(entry != NULL, "Expected entry != NULL, got %p\n", entry);
467 item = CONTAINING_RECORD(entry, struct item, entry);
468 ok(item->value == i, "Expected item->value == %u, got %u\n", i, item->value);
469 entry = item->entry.Next;
470 HeapFree(GetProcessHeap(), 0, item);
471 }
472 ok(entry == NULL, "Expected entry == NULL, got %p\n", entry);
473 size = QueryDepthSList(&slist_header);
474 ok(size == 0, "Expected size == 0, got %u\n", size);
475 entry = InterlockedPopEntrySList(&slist_header);
476 ok(entry == NULL, "Expected entry == NULL, got %p\n", entry);
477 }
478
479 static void test_event(void)
480 {
481 HANDLE handle, handle2;
482 SECURITY_ATTRIBUTES sa;
483 SECURITY_DESCRIPTOR sd;
484 ACL acl;
485 DWORD ret;
486 BOOL val;
487
488 /* no sd */
489 handle = CreateEventA(NULL, FALSE, FALSE, __FILE__ ": Test Event");
490 ok(handle != NULL, "CreateEventW with blank sd failed with error %d\n", GetLastError());
491 CloseHandle(handle);
492
493 sa.nLength = sizeof(sa);
494 sa.lpSecurityDescriptor = &sd;
495 sa.bInheritHandle = FALSE;
496
497 InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);
498
499 /* blank sd */
500 handle = CreateEventA(&sa, FALSE, FALSE, __FILE__ ": Test Event");
501 ok(handle != NULL, "CreateEventW with blank sd failed with error %d\n", GetLastError());
502 CloseHandle(handle);
503
504 /* sd with NULL dacl */
505 SetSecurityDescriptorDacl(&sd, TRUE, NULL, FALSE);
506 handle = CreateEventA(&sa, FALSE, FALSE, __FILE__ ": Test Event");
507 ok(handle != NULL, "CreateEventW with blank sd failed with error %d\n", GetLastError());
508 CloseHandle(handle);
509
510 /* sd with empty dacl */
511 InitializeAcl(&acl, sizeof(acl), ACL_REVISION);
512 SetSecurityDescriptorDacl(&sd, TRUE, &acl, FALSE);
513 handle = CreateEventA(&sa, FALSE, FALSE, __FILE__ ": Test Event");
514 ok(handle != NULL, "CreateEventW with blank sd failed with error %d\n", GetLastError());
515 CloseHandle(handle);
516
517 /* test case sensitivity */
518
519 SetLastError(0xdeadbeef);
520 handle = CreateEventA(NULL, FALSE, FALSE, __FILE__ ": Test Event");
521 ok( handle != NULL, "CreateEvent failed with error %u\n", GetLastError());
522 ok( GetLastError() == 0, "wrong error %u\n", GetLastError());
523
524 SetLastError(0xdeadbeef);
525 handle2 = CreateEventA(NULL, FALSE, FALSE, __FILE__ ": Test Event");
526 ok( handle2 != NULL, "CreateEvent failed with error %d\n", GetLastError());
527 ok( GetLastError() == ERROR_ALREADY_EXISTS, "wrong error %u\n", GetLastError());
528 CloseHandle( handle2 );
529
530 SetLastError(0xdeadbeef);
531 handle2 = CreateEventA(NULL, FALSE, FALSE, __FILE__ ": TEST EVENT");
532 ok( handle2 != NULL, "CreateEvent failed with error %d\n", GetLastError());
533 ok( GetLastError() == 0, "wrong error %u\n", GetLastError());
534 CloseHandle( handle2 );
535
536 SetLastError(0xdeadbeef);
537 handle2 = OpenEventA( EVENT_ALL_ACCESS, FALSE, __FILE__ ": Test Event");
538 ok( handle2 != NULL, "OpenEvent failed with error %d\n", GetLastError());
539 CloseHandle( handle2 );
540
541 SetLastError(0xdeadbeef);
542 handle2 = OpenEventA( EVENT_ALL_ACCESS, FALSE, __FILE__ ": TEST EVENT");
543 ok( !handle2, "OpenEvent succeeded\n");
544 ok( GetLastError() == ERROR_FILE_NOT_FOUND, "wrong error %u\n", GetLastError());
545
546 CloseHandle( handle );
547
548 /* resource notifications are events too */
549
550 if (!pCreateMemoryResourceNotification || !pQueryMemoryResourceNotification)
551 {
552 trace( "memory resource notifications not supported\n" );
553 return;
554 }
555 handle = pCreateMemoryResourceNotification( HighMemoryResourceNotification + 1 );
556 ok( !handle, "CreateMemoryResourceNotification succeeded\n" );
557 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
558 ret = pQueryMemoryResourceNotification( handle, &val );
559 ok( !ret, "QueryMemoryResourceNotification succeeded\n" );
560 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
561
562 handle = pCreateMemoryResourceNotification( LowMemoryResourceNotification );
563 ok( handle != 0, "CreateMemoryResourceNotification failed err %u\n", GetLastError() );
564 ret = WaitForSingleObject( handle, 10 );
565 ok( ret == WAIT_OBJECT_0 || ret == WAIT_TIMEOUT, "WaitForSingleObject wrong ret %u\n", ret );
566
567 val = ~0;
568 ret = pQueryMemoryResourceNotification( handle, &val );
569 ok( ret, "QueryMemoryResourceNotification failed err %u\n", GetLastError() );
570 ok( val == FALSE || val == TRUE, "wrong value %u\n", val );
571 ret = CloseHandle( handle );
572 ok( ret, "CloseHandle failed err %u\n", GetLastError() );
573
574 handle = CreateEventA(NULL, FALSE, FALSE, __FILE__ ": Test Event");
575 val = ~0;
576 ret = pQueryMemoryResourceNotification( handle, &val );
577 ok( ret, "QueryMemoryResourceNotification failed err %u\n", GetLastError() );
578 ok( val == FALSE || val == TRUE, "wrong value %u\n", val );
579 CloseHandle( handle );
580 }
581
582 static void test_semaphore(void)
583 {
584 HANDLE handle, handle2;
585
586 /* test case sensitivity */
587
588 SetLastError(0xdeadbeef);
589 handle = CreateSemaphoreA(NULL, 0, 1, __FILE__ ": Test Semaphore");
590 ok(handle != NULL, "CreateSemaphore failed with error %u\n", GetLastError());
591 ok(GetLastError() == 0, "wrong error %u\n", GetLastError());
592
593 SetLastError(0xdeadbeef);
594 handle2 = CreateSemaphoreA(NULL, 0, 1, __FILE__ ": Test Semaphore");
595 ok( handle2 != NULL, "CreateSemaphore failed with error %d\n", GetLastError());
596 ok( GetLastError() == ERROR_ALREADY_EXISTS, "wrong error %u\n", GetLastError());
597 CloseHandle( handle2 );
598
599 SetLastError(0xdeadbeef);
600 handle2 = CreateSemaphoreA(NULL, 0, 1, __FILE__ ": TEST SEMAPHORE");
601 ok( handle2 != NULL, "CreateSemaphore failed with error %d\n", GetLastError());
602 ok( GetLastError() == 0, "wrong error %u\n", GetLastError());
603 CloseHandle( handle2 );
604
605 SetLastError(0xdeadbeef);
606 handle2 = OpenSemaphoreA( SEMAPHORE_ALL_ACCESS, FALSE, __FILE__ ": Test Semaphore");
607 ok( handle2 != NULL, "OpenSemaphore failed with error %d\n", GetLastError());
608 CloseHandle( handle2 );
609
610 SetLastError(0xdeadbeef);
611 handle2 = OpenSemaphoreA( SEMAPHORE_ALL_ACCESS, FALSE, __FILE__ ": TEST SEMAPHORE");
612 ok( !handle2, "OpenSemaphore succeeded\n");
613 ok( GetLastError() == ERROR_FILE_NOT_FOUND, "wrong error %u\n", GetLastError());
614
615 CloseHandle( handle );
616 }
617
618 static void test_waitable_timer(void)
619 {
620 HANDLE handle, handle2;
621
622 if (!pCreateWaitableTimerA || !pOpenWaitableTimerA)
623 {
624 win_skip("{Create,Open}WaitableTimerA() is not available\n");
625 return;
626 }
627
628 /* test case sensitivity */
629
630 SetLastError(0xdeadbeef);
631 handle = pCreateWaitableTimerA(NULL, FALSE, __FILE__ ": Test WaitableTimer");
632 ok(handle != NULL, "CreateWaitableTimer failed with error %u\n", GetLastError());
633 ok(GetLastError() == 0, "wrong error %u\n", GetLastError());
634
635 SetLastError(0xdeadbeef);
636 handle2 = pCreateWaitableTimerA(NULL, FALSE, __FILE__ ": Test WaitableTimer");
637 ok( handle2 != NULL, "CreateWaitableTimer failed with error %d\n", GetLastError());
638 ok( GetLastError() == ERROR_ALREADY_EXISTS, "wrong error %u\n", GetLastError());
639 CloseHandle( handle2 );
640
641 SetLastError(0xdeadbeef);
642 handle2 = pCreateWaitableTimerA(NULL, FALSE, __FILE__ ": TEST WAITABLETIMER");
643 ok( handle2 != NULL, "CreateWaitableTimer failed with error %d\n", GetLastError());
644 ok( GetLastError() == 0, "wrong error %u\n", GetLastError());
645 CloseHandle( handle2 );
646
647 SetLastError(0xdeadbeef);
648 handle2 = pOpenWaitableTimerA( TIMER_ALL_ACCESS, FALSE, __FILE__ ": Test WaitableTimer");
649 ok( handle2 != NULL, "OpenWaitableTimer failed with error %d\n", GetLastError());
650 CloseHandle( handle2 );
651
652 SetLastError(0xdeadbeef);
653 handle2 = pOpenWaitableTimerA( TIMER_ALL_ACCESS, FALSE, __FILE__ ": TEST WAITABLETIMER");
654 ok( !handle2, "OpenWaitableTimer succeeded\n");
655 ok( GetLastError() == ERROR_FILE_NOT_FOUND ||
656 GetLastError() == ERROR_INVALID_NAME, /* win98 */
657 "wrong error %u\n", GetLastError());
658
659 CloseHandle( handle );
660 }
661
662 static HANDLE sem = 0;
663
664 static void CALLBACK iocp_callback(DWORD dwErrorCode, DWORD dwNumberOfBytesTransferred, LPOVERLAPPED lpOverlapped)
665 {
666 ReleaseSemaphore(sem, 1, NULL);
667 }
668
669 static BOOL (WINAPI *p_BindIoCompletionCallback)( HANDLE FileHandle, LPOVERLAPPED_COMPLETION_ROUTINE Function, ULONG Flags) = NULL;
670
671 static void test_iocp_callback(void)
672 {
673 char temp_path[MAX_PATH];
674 char filename[MAX_PATH];
675 DWORD ret;
676 BOOL retb;
677 static const char prefix[] = "pfx";
678 HANDLE hFile;
679 HMODULE hmod = GetModuleHandleA("kernel32.dll");
680 DWORD bytesWritten;
681 const char *buffer = "12345678123456781234567812345678";
682 OVERLAPPED overlapped;
683
684 p_BindIoCompletionCallback = (void*)GetProcAddress(hmod, "BindIoCompletionCallback");
685 if(!p_BindIoCompletionCallback) {
686 win_skip("BindIoCompletionCallback not found in this DLL\n");
687 return;
688 }
689
690 sem = CreateSemaphoreW(NULL, 0, 1, NULL);
691 ok(sem != INVALID_HANDLE_VALUE, "Creating a semaphore failed\n");
692
693 ret = GetTempPathA(MAX_PATH, temp_path);
694 ok(ret != 0, "GetTempPathA error %d\n", GetLastError());
695 ok(ret < MAX_PATH, "temp path should fit into MAX_PATH\n");
696
697 ret = GetTempFileNameA(temp_path, prefix, 0, filename);
698 ok(ret != 0, "GetTempFileNameA error %d\n", GetLastError());
699
700 hFile = CreateFileA(filename, GENERIC_READ | GENERIC_WRITE, 0, NULL,
701 CREATE_ALWAYS, FILE_FLAG_RANDOM_ACCESS, 0);
702 ok(hFile != INVALID_HANDLE_VALUE, "CreateFileA: error %d\n", GetLastError());
703
704 retb = p_BindIoCompletionCallback(hFile, iocp_callback, 0);
705 ok(retb == FALSE, "BindIoCompletionCallback succeeded on a file that wasn't created with FILE_FLAG_OVERLAPPED\n");
706 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Last error is %d\n", GetLastError());
707
708 ret = CloseHandle(hFile);
709 ok( ret, "CloseHandle: error %d\n", GetLastError());
710 ret = DeleteFileA(filename);
711 ok( ret, "DeleteFileA: error %d\n", GetLastError());
712
713 hFile = CreateFileA(filename, GENERIC_READ | GENERIC_WRITE, 0, NULL,
714 CREATE_ALWAYS, FILE_FLAG_RANDOM_ACCESS | FILE_FLAG_OVERLAPPED, 0);
715 ok(hFile != INVALID_HANDLE_VALUE, "CreateFileA: error %d\n", GetLastError());
716
717 retb = p_BindIoCompletionCallback(hFile, iocp_callback, 0);
718 ok(retb == TRUE, "BindIoCompletionCallback failed\n");
719
720 memset(&overlapped, 0, sizeof(overlapped));
721 retb = WriteFile(hFile, buffer, 4, &bytesWritten, &overlapped);
722 ok(retb == TRUE || GetLastError() == ERROR_IO_PENDING, "WriteFile failed, lastError = %d\n", GetLastError());
723
724 ret = WaitForSingleObject(sem, 5000);
725 ok(ret == WAIT_OBJECT_0, "Wait for the IO completion callback failed\n");
726 CloseHandle(sem);
727
728 retb = p_BindIoCompletionCallback(hFile, iocp_callback, 0);
729 ok(retb == FALSE, "BindIoCompletionCallback succeeded when setting the same callback on the file again\n");
730 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Last error is %d\n", GetLastError());
731 retb = p_BindIoCompletionCallback(hFile, NULL, 0);
732 ok(retb == FALSE, "BindIoCompletionCallback succeeded when setting the callback to NULL\n");
733 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Last error is %d\n", GetLastError());
734
735 ret = CloseHandle(hFile);
736 ok( ret, "CloseHandle: error %d\n", GetLastError());
737 ret = DeleteFileA(filename);
738 ok( ret, "DeleteFileA: error %d\n", GetLastError());
739
740 /* win2k3 requires the Flags parameter to be zero */
741 SetLastError(0xdeadbeef);
742 hFile = CreateFileA(filename, GENERIC_READ | GENERIC_WRITE, 0, NULL,
743 CREATE_ALWAYS, FILE_FLAG_RANDOM_ACCESS | FILE_FLAG_OVERLAPPED, 0);
744 ok(hFile != INVALID_HANDLE_VALUE, "CreateFileA: error %d\n", GetLastError());
745 retb = p_BindIoCompletionCallback(hFile, iocp_callback, 12345);
746 if (!retb)
747 ok(GetLastError() == ERROR_INVALID_PARAMETER,
748 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
749 else
750 ok(retb == TRUE, "BindIoCompletionCallback failed with Flags != 0\n");
751 ret = CloseHandle(hFile);
752 ok( ret, "CloseHandle: error %d\n", GetLastError());
753 ret = DeleteFileA(filename);
754 ok( ret, "DeleteFileA: error %d\n", GetLastError());
755
756 retb = p_BindIoCompletionCallback(NULL, iocp_callback, 0);
757 ok(retb == FALSE, "BindIoCompletionCallback succeeded on a NULL file\n");
758 ok(GetLastError() == ERROR_INVALID_HANDLE ||
759 GetLastError() == ERROR_INVALID_PARAMETER, /* vista */
760 "Last error is %d\n", GetLastError());
761 }
762
763 static void CALLBACK timer_queue_cb1(PVOID p, BOOLEAN timedOut)
764 {
765 int *pn = p;
766 ok(timedOut, "Timer callbacks should always time out\n");
767 ++*pn;
768 }
769
770 struct timer_queue_data1
771 {
772 int num_calls;
773 int max_calls;
774 HANDLE q, t;
775 };
776
777 static void CALLBACK timer_queue_cb2(PVOID p, BOOLEAN timedOut)
778 {
779 struct timer_queue_data1 *d = p;
780 ok(timedOut, "Timer callbacks should always time out\n");
781 if (d->t && ++d->num_calls == d->max_calls)
782 {
783 BOOL ret;
784 SetLastError(0xdeadbeef);
785 /* Note, XP SP2 does *not* do any deadlock checking, so passing
786 INVALID_HANDLE_VALUE here will just hang. */
787 ret = pDeleteTimerQueueTimer(d->q, d->t, NULL);
788 ok(!ret, "DeleteTimerQueueTimer\n");
789 ok(GetLastError() == ERROR_IO_PENDING, "DeleteTimerQueueTimer\n");
790 }
791 }
792
793 static void CALLBACK timer_queue_cb3(PVOID p, BOOLEAN timedOut)
794 {
795 struct timer_queue_data1 *d = p;
796 ok(timedOut, "Timer callbacks should always time out\n");
797 if (d->t && ++d->num_calls == d->max_calls)
798 {
799 /* Basically kill the timer since it won't have time to run
800 again. */
801 BOOL ret = pChangeTimerQueueTimer(d->q, d->t, 10000, 0);
802 ok(ret, "ChangeTimerQueueTimer\n");
803 }
804 }
805
806 static void CALLBACK timer_queue_cb4(PVOID p, BOOLEAN timedOut)
807 {
808 struct timer_queue_data1 *d = p;
809 ok(timedOut, "Timer callbacks should always time out\n");
810 if (d->t)
811 {
812 /* This tests whether a timer gets flagged for deletion before
813 or after the callback runs. If we start this timer with a
814 period of zero (run once), then ChangeTimerQueueTimer will
815 fail if the timer is already flagged. Hence we really run
816 only once. Otherwise we will run multiple times. */
817 BOOL ret = pChangeTimerQueueTimer(d->q, d->t, 50, 50);
818 ok(ret, "ChangeTimerQueueTimer\n");
819 ++d->num_calls;
820 }
821 }
822
823 static void CALLBACK timer_queue_cb5(PVOID p, BOOLEAN timedOut)
824 {
825 DWORD_PTR delay = (DWORD_PTR) p;
826 ok(timedOut, "Timer callbacks should always time out\n");
827 if (delay)
828 Sleep(delay);
829 }
830
831 static void CALLBACK timer_queue_cb6(PVOID p, BOOLEAN timedOut)
832 {
833 struct timer_queue_data1 *d = p;
834 ok(timedOut, "Timer callbacks should always time out\n");
835 /* This tests an original implementation bug where a deleted timer may get
836 to run, but it is tricky to set up. */
837 if (d->q && d->num_calls++ == 0)
838 {
839 /* First run: delete ourselves, then insert and remove a timer
840 that goes in front of us in the sorted timeout list. Once
841 removed, we will still timeout at the faster timer's due time,
842 but this should be a no-op if we are bug-free. There should
843 not be a second run. We can test the value of num_calls later. */
844 BOOL ret;
845 HANDLE t;
846
847 /* The delete will pend while we are in this callback. */
848 SetLastError(0xdeadbeef);
849 ret = pDeleteTimerQueueTimer(d->q, d->t, NULL);
850 ok(!ret, "DeleteTimerQueueTimer\n");
851 ok(GetLastError() == ERROR_IO_PENDING, "DeleteTimerQueueTimer\n");
852
853 ret = pCreateTimerQueueTimer(&t, d->q, timer_queue_cb1, NULL, 100, 0, 0);
854 ok(ret, "CreateTimerQueueTimer\n");
855 ok(t != NULL, "CreateTimerQueueTimer\n");
856
857 ret = pDeleteTimerQueueTimer(d->q, t, INVALID_HANDLE_VALUE);
858 ok(ret, "DeleteTimerQueueTimer\n");
859
860 /* Now we stay alive by hanging around in the callback. */
861 Sleep(500);
862 }
863 }
864
865 static void test_timer_queue(void)
866 {
867 HANDLE q, t0, t1, t2, t3, t4, t5;
868 int n0, n1, n2, n3, n4, n5;
869 struct timer_queue_data1 d1, d2, d3, d4;
870 HANDLE e, et1, et2;
871 BOOL ret, ret0;
872
873 if (!pChangeTimerQueueTimer || !pCreateTimerQueue || !pCreateTimerQueueTimer
874 || !pDeleteTimerQueueEx || !pDeleteTimerQueueTimer)
875 {
876 win_skip("TimerQueue API not present\n");
877 return;
878 }
879
880 /* Test asynchronous deletion of the queue. */
881 q = pCreateTimerQueue();
882 ok(q != NULL, "CreateTimerQueue\n");
883
884 SetLastError(0xdeadbeef);
885 ret = pDeleteTimerQueueEx(q, NULL);
886 ok(ret /* vista */ || GetLastError() == ERROR_IO_PENDING,
887 "DeleteTimerQueueEx, GetLastError: expected ERROR_IO_PENDING, got %d\n",
888 GetLastError());
889
890 /* Test synchronous deletion of the queue and running timers. */
891 q = pCreateTimerQueue();
892 ok(q != NULL, "CreateTimerQueue\n");
893
894 /* Not called. */
895 t0 = NULL;
896 n0 = 0;
897 ret = pCreateTimerQueueTimer(&t0, q, timer_queue_cb1, &n0, 0,
898 300, 0);
899 ok(ret, "CreateTimerQueueTimer\n");
900 ok(t0 != NULL, "CreateTimerQueueTimer\n");
901 ret0 = pDeleteTimerQueueTimer(q, t0, NULL);
902 ok((!ret0 && GetLastError() == ERROR_IO_PENDING) ||
903 broken(ret0), /* Win 2000 & XP & 2003 */
904 "DeleteTimerQueueTimer ret=%d le=%u\n", ret0, GetLastError());
905
906 /* Called once. */
907 t1 = NULL;
908 n1 = 0;
909 ret = pCreateTimerQueueTimer(&t1, q, timer_queue_cb1, &n1, 0,
910 0, 0);
911 ok(ret, "CreateTimerQueueTimer\n");
912 ok(t1 != NULL, "CreateTimerQueueTimer\n");
913
914 /* A slow one. */
915 t2 = NULL;
916 n2 = 0;
917 ret = pCreateTimerQueueTimer(&t2, q, timer_queue_cb1, &n2, 0,
918 100, 0);
919 ok(ret, "CreateTimerQueueTimer\n");
920 ok(t2 != NULL, "CreateTimerQueueTimer\n");
921
922 /* A fast one. */
923 t3 = NULL;
924 n3 = 0;
925 ret = pCreateTimerQueueTimer(&t3, q, timer_queue_cb1, &n3, 0,
926 10, 0);
927 ok(ret, "CreateTimerQueueTimer\n");
928 ok(t3 != NULL, "CreateTimerQueueTimer\n");
929
930 /* Start really late (it won't start). */
931 t4 = NULL;
932 n4 = 0;
933 ret = pCreateTimerQueueTimer(&t4, q, timer_queue_cb1, &n4, 10000,
934 10, 0);
935 ok(ret, "CreateTimerQueueTimer\n");
936 ok(t4 != NULL, "CreateTimerQueueTimer\n");
937
938 /* Start soon, but delay so long it won't run again. */
939 t5 = NULL;
940 n5 = 0;
941 ret = pCreateTimerQueueTimer(&t5, q, timer_queue_cb1, &n5, 0,
942 10000, 0);
943 ok(ret, "CreateTimerQueueTimer\n");
944 ok(t5 != NULL, "CreateTimerQueueTimer\n");
945
946 /* Give them a chance to do some work. */
947 Sleep(500);
948
949 /* Test deleting a once-only timer. */
950 ret = pDeleteTimerQueueTimer(q, t1, INVALID_HANDLE_VALUE);
951 ok(ret, "DeleteTimerQueueTimer\n");
952
953 /* A periodic timer. */
954 ret = pDeleteTimerQueueTimer(q, t2, INVALID_HANDLE_VALUE);
955 ok(ret, "DeleteTimerQueueTimer\n");
956
957 ret = pDeleteTimerQueueEx(q, INVALID_HANDLE_VALUE);
958 ok(ret, "DeleteTimerQueueEx\n");
959 todo_wine
960 ok(n0 == 1 || broken(ret0 && n0 == 0), "Timer callback 0 expected 1 got %d\n", n0);
961 ok(n1 == 1, "Timer callback 1 expected 1 got %d\n", n1);
962 ok(n2 < n3, "Timer callback 2 & 3 expected %d < %d\n", n2, n3);
963 ok(n4 == 0, "Timer callback 4 expected 0 got %d\n", n4);
964 ok(n5 == 1, "Timer callback 5 expected 1 got %d\n", n5);
965
966 /* Test synchronous deletion of the timer/queue with event trigger. */
967 e = CreateEventW(NULL, TRUE, FALSE, NULL);
968 et1 = CreateEventW(NULL, TRUE, FALSE, NULL);
969 et2 = CreateEventW(NULL, TRUE, FALSE, NULL);
970 if (!e || !et1 || !et2)
971 {
972 skip("Failed to create timer queue descruction event\n");
973 return;
974 }
975
976 q = pCreateTimerQueue();
977 ok(q != NULL, "CreateTimerQueue\n");
978
979 /* Run once and finish quickly (should be done when we delete it). */
980 t1 = NULL;
981 ret = pCreateTimerQueueTimer(&t1, q, timer_queue_cb5, NULL, 0, 0, 0);
982 ok(ret, "CreateTimerQueueTimer\n");
983 ok(t1 != NULL, "CreateTimerQueueTimer\n");
984
985 /* Run once and finish slowly (shouldn't be done when we delete it). */
986 t2 = NULL;
987 ret = pCreateTimerQueueTimer(&t2, q, timer_queue_cb5, (PVOID) 1000, 0,
988 0, 0);
989 ok(ret, "CreateTimerQueueTimer\n");
990 ok(t2 != NULL, "CreateTimerQueueTimer\n");
991
992 /* Run once and finish quickly (should be done when we delete it). */
993 t3 = NULL;
994 ret = pCreateTimerQueueTimer(&t3, q, timer_queue_cb5, NULL, 0, 0, 0);
995 ok(ret, "CreateTimerQueueTimer\n");
996 ok(t3 != NULL, "CreateTimerQueueTimer\n");
997
998 /* Run once and finish slowly (shouldn't be done when we delete it). */
999 t4 = NULL;
1000 ret = pCreateTimerQueueTimer(&t4, q, timer_queue_cb5, (PVOID) 1000, 0,
1001 0, 0);
1002 ok(ret, "CreateTimerQueueTimer\n");
1003 ok(t4 != NULL, "CreateTimerQueueTimer\n");
1004
1005 /* Give them a chance to start. */
1006 Sleep(400);
1007
1008 /* DeleteTimerQueueTimer always returns PENDING with a NULL event,
1009 even if the timer is finished. */
1010 SetLastError(0xdeadbeef);
1011 ret = pDeleteTimerQueueTimer(q, t1, NULL);
1012 ok(ret /* vista */ || GetLastError() == ERROR_IO_PENDING,
1013 "DeleteTimerQueueTimer, GetLastError: expected ERROR_IO_PENDING, got %d\n",
1014 GetLastError());
1015
1016 SetLastError(0xdeadbeef);
1017 ret = pDeleteTimerQueueTimer(q, t2, NULL);
1018 ok(!ret, "DeleteTimerQueueTimer call was expected to fail\n");
1019 ok(GetLastError() == ERROR_IO_PENDING,
1020 "DeleteTimerQueueTimer, GetLastError: expected ERROR_IO_PENDING, got %d\n",
1021 GetLastError());
1022
1023 SetLastError(0xdeadbeef);
1024 ret = pDeleteTimerQueueTimer(q, t3, et1);
1025 ok(ret, "DeleteTimerQueueTimer call was expected to fail\n");
1026 ok(GetLastError() == 0xdeadbeef,
1027 "DeleteTimerQueueTimer, GetLastError: expected 0xdeadbeef, got %d\n",
1028 GetLastError());
1029 ok(WaitForSingleObject(et1, 250) == WAIT_OBJECT_0,
1030 "Timer destruction event not triggered\n");
1031
1032 SetLastError(0xdeadbeef);
1033 ret = pDeleteTimerQueueTimer(q, t4, et2);
1034 ok(!ret, "DeleteTimerQueueTimer call was expected to fail\n");
1035 ok(GetLastError() == ERROR_IO_PENDING,
1036 "DeleteTimerQueueTimer, GetLastError: expected ERROR_IO_PENDING, got %d\n",
1037 GetLastError());
1038 ok(WaitForSingleObject(et2, 1000) == WAIT_OBJECT_0,
1039 "Timer destruction event not triggered\n");
1040
1041 SetLastError(0xdeadbeef);
1042 ret = pDeleteTimerQueueEx(q, e);
1043 ok(ret /* vista */ || GetLastError() == ERROR_IO_PENDING,
1044 "DeleteTimerQueueEx, GetLastError: expected ERROR_IO_PENDING, got %d\n",
1045 GetLastError());
1046 ok(WaitForSingleObject(e, 250) == WAIT_OBJECT_0,
1047 "Queue destruction event not triggered\n");
1048 CloseHandle(e);
1049
1050 /* Test deleting/changing a timer in execution. */
1051 q = pCreateTimerQueue();
1052 ok(q != NULL, "CreateTimerQueue\n");
1053
1054 /* Test changing a once-only timer before it fires (this is allowed,
1055 whereas after it fires you cannot). */
1056 n1 = 0;
1057 ret = pCreateTimerQueueTimer(&t1, q, timer_queue_cb1, &n1, 10000,
1058 0, 0);
1059 ok(ret, "CreateTimerQueueTimer\n");
1060 ok(t1 != NULL, "CreateTimerQueueTimer\n");
1061 ret = pChangeTimerQueueTimer(q, t1, 0, 0);
1062 ok(ret, "ChangeTimerQueueTimer\n");
1063
1064 d2.t = t2 = NULL;
1065 d2.num_calls = 0;
1066 d2.max_calls = 3;
1067 d2.q = q;
1068 ret = pCreateTimerQueueTimer(&t2, q, timer_queue_cb2, &d2, 10,
1069 10, 0);
1070 d2.t = t2;
1071 ok(ret, "CreateTimerQueueTimer\n");
1072 ok(t2 != NULL, "CreateTimerQueueTimer\n");
1073
1074 d3.t = t3 = NULL;
1075 d3.num_calls = 0;
1076 d3.max_calls = 4;
1077 d3.q = q;
1078 ret = pCreateTimerQueueTimer(&t3, q, timer_queue_cb3, &d3, 10,
1079 10, 0);
1080 d3.t = t3;
1081 ok(ret, "CreateTimerQueueTimer\n");
1082 ok(t3 != NULL, "CreateTimerQueueTimer\n");
1083
1084 d4.t = t4 = NULL;
1085 d4.num_calls = 0;
1086 d4.q = q;
1087 ret = pCreateTimerQueueTimer(&t4, q, timer_queue_cb4, &d4, 10,
1088 0, 0);
1089 d4.t = t4;
1090 ok(ret, "CreateTimerQueueTimer\n");
1091 ok(t4 != NULL, "CreateTimerQueueTimer\n");
1092
1093 Sleep(500);
1094
1095 ret = pDeleteTimerQueueEx(q, INVALID_HANDLE_VALUE);
1096 ok(ret, "DeleteTimerQueueEx\n");
1097 ok(n1 == 1, "ChangeTimerQueueTimer\n");
1098 ok(d2.num_calls == d2.max_calls, "DeleteTimerQueueTimer\n");
1099 ok(d3.num_calls == d3.max_calls, "ChangeTimerQueueTimer\n");
1100 ok(d4.num_calls == 1, "Timer flagged for deletion incorrectly\n");
1101
1102 /* Test an obscure bug that was in the original implementation. */
1103 q = pCreateTimerQueue();
1104 ok(q != NULL, "CreateTimerQueue\n");
1105
1106 /* All the work is done in the callback. */
1107 d1.t = t1 = NULL;
1108 d1.num_calls = 0;
1109 d1.q = q;
1110 ret = pCreateTimerQueueTimer(&t1, q, timer_queue_cb6, &d1, 100,
1111 100, WT_EXECUTELONGFUNCTION);
1112 d1.t = t1;
1113 ok(ret, "CreateTimerQueueTimer\n");
1114 ok(t1 != NULL, "CreateTimerQueueTimer\n");
1115
1116 Sleep(750);
1117
1118 SetLastError(0xdeadbeef);
1119 ret = pDeleteTimerQueueEx(q, NULL);
1120 ok(ret /* vista */ || GetLastError() == ERROR_IO_PENDING,
1121 "DeleteTimerQueueEx, GetLastError: expected ERROR_IO_PENDING, got %d\n",
1122 GetLastError());
1123 ok(d1.num_calls == 1, "DeleteTimerQueueTimer\n");
1124
1125 /* Test functions on the default timer queue. */
1126 t1 = NULL;
1127 n1 = 0;
1128 ret = pCreateTimerQueueTimer(&t1, NULL, timer_queue_cb1, &n1, 1000,
1129 1000, 0);
1130 ok(ret, "CreateTimerQueueTimer, default queue\n");
1131 ok(t1 != NULL, "CreateTimerQueueTimer, default queue\n");
1132
1133 ret = pChangeTimerQueueTimer(NULL, t1, 2000, 2000);
1134 ok(ret, "ChangeTimerQueueTimer, default queue\n");
1135
1136 ret = pDeleteTimerQueueTimer(NULL, t1, INVALID_HANDLE_VALUE);
1137 ok(ret, "DeleteTimerQueueTimer, default queue\n");
1138
1139 /* Try mixing default and non-default queues. Apparently this works. */
1140 q = pCreateTimerQueue();
1141 ok(q != NULL, "CreateTimerQueue\n");
1142
1143 t1 = NULL;
1144 n1 = 0;
1145 ret = pCreateTimerQueueTimer(&t1, q, timer_queue_cb1, &n1, 1000,
1146 1000, 0);
1147 ok(ret, "CreateTimerQueueTimer\n");
1148 ok(t1 != NULL, "CreateTimerQueueTimer\n");
1149
1150 t2 = NULL;
1151 n2 = 0;
1152 ret = pCreateTimerQueueTimer(&t2, NULL, timer_queue_cb1, &n2, 1000,
1153 1000, 0);
1154 ok(ret, "CreateTimerQueueTimer\n");
1155 ok(t2 != NULL, "CreateTimerQueueTimer\n");
1156
1157 ret = pChangeTimerQueueTimer(NULL, t1, 2000, 2000);
1158 ok(ret, "ChangeTimerQueueTimer\n");
1159
1160 ret = pChangeTimerQueueTimer(q, t2, 2000, 2000);
1161 ok(ret, "ChangeTimerQueueTimer\n");
1162
1163 ret = pDeleteTimerQueueTimer(NULL, t1, INVALID_HANDLE_VALUE);
1164 ok(ret, "DeleteTimerQueueTimer\n");
1165
1166 ret = pDeleteTimerQueueTimer(q, t2, INVALID_HANDLE_VALUE);
1167 ok(ret, "DeleteTimerQueueTimer\n");
1168
1169 /* Try to delete the default queue? In any case: not allowed. */
1170 SetLastError(0xdeadbeef);
1171 ret = pDeleteTimerQueueEx(NULL, NULL);
1172 ok(!ret, "DeleteTimerQueueEx call was expected to fail\n");
1173 ok(GetLastError() == ERROR_INVALID_HANDLE,
1174 "DeleteTimerQueueEx, GetLastError: expected ERROR_INVALID_HANDLE, got %d\n",
1175 GetLastError());
1176
1177 SetLastError(0xdeadbeef);
1178 ret = pDeleteTimerQueueEx(q, NULL);
1179 ok(ret /* vista */ || GetLastError() == ERROR_IO_PENDING,
1180 "DeleteTimerQueueEx, GetLastError: expected ERROR_IO_PENDING, got %d\n",
1181 GetLastError());
1182 }
1183
1184 static HANDLE modify_handle(HANDLE handle, DWORD modify)
1185 {
1186 DWORD tmp = HandleToULong(handle);
1187 tmp |= modify;
1188 return ULongToHandle(tmp);
1189 }
1190
1191 static void test_WaitForSingleObject(void)
1192 {
1193 HANDLE signaled, nonsignaled, invalid;
1194 LARGE_INTEGER timeout;
1195 NTSTATUS status;
1196 DWORD ret;
1197
1198 signaled = CreateEventW(NULL, TRUE, TRUE, NULL);
1199 nonsignaled = CreateEventW(NULL, TRUE, FALSE, NULL);
1200 invalid = (HANDLE) 0xdeadbee0;
1201
1202 /* invalid handle with different values for lower 2 bits */
1203 SetLastError(0xdeadbeef);
1204 ret = WaitForSingleObject(invalid, 0);
1205 ok(ret == WAIT_FAILED, "expected WAIT_FAILED, got %d\n", ret);
1206 ok(GetLastError() == ERROR_INVALID_HANDLE, "expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
1207
1208 SetLastError(0xdeadbeef);
1209 ret = WaitForSingleObject(modify_handle(invalid, 1), 0);
1210 ok(ret == WAIT_FAILED, "expected WAIT_FAILED, got %d\n", ret);
1211 ok(GetLastError() == ERROR_INVALID_HANDLE, "expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
1212
1213 SetLastError(0xdeadbeef);
1214 ret = WaitForSingleObject(modify_handle(invalid, 2), 0);
1215 ok(ret == WAIT_FAILED, "expected WAIT_FAILED, got %d\n", ret);
1216 ok(GetLastError() == ERROR_INVALID_HANDLE, "expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
1217
1218 SetLastError(0xdeadbeef);
1219 ret = WaitForSingleObject(modify_handle(invalid, 3), 0);
1220 ok(ret == WAIT_FAILED, "expected WAIT_FAILED, got %d\n", ret);
1221 ok(GetLastError() == ERROR_INVALID_HANDLE, "expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
1222
1223 /* valid handle with different values for lower 2 bits */
1224 SetLastError(0xdeadbeef);
1225 ret = WaitForSingleObject(nonsignaled, 0);
1226 ok(ret == WAIT_TIMEOUT, "expected WAIT_TIMEOUT, got %d\n", ret);
1227 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
1228
1229 SetLastError(0xdeadbeef);
1230 ret = WaitForSingleObject(modify_handle(nonsignaled, 1), 0);
1231 ok(ret == WAIT_TIMEOUT, "expected WAIT_TIMEOUT, got %d\n", ret);
1232 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
1233
1234 SetLastError(0xdeadbeef);
1235 ret = WaitForSingleObject(modify_handle(nonsignaled, 2), 0);
1236 ok(ret == WAIT_TIMEOUT, "expected WAIT_TIMEOUT, got %d\n", ret);
1237 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
1238
1239 SetLastError(0xdeadbeef);
1240 ret = WaitForSingleObject(modify_handle(nonsignaled, 3), 0);
1241 ok(ret == WAIT_TIMEOUT, "expected WAIT_TIMEOUT, got %d\n", ret);
1242 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
1243
1244 /* valid handle with different values for lower 2 bits */
1245 SetLastError(0xdeadbeef);
1246 ret = WaitForSingleObject(signaled, 0);
1247 ok(ret == WAIT_OBJECT_0, "expected WAIT_OBJECT_0, got %d\n", ret);
1248 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
1249
1250 SetLastError(0xdeadbeef);
1251 ret = WaitForSingleObject(modify_handle(signaled, 1), 0);
1252 ok(ret == WAIT_OBJECT_0, "expected WAIT_OBJECT_0, got %d\n", ret);
1253 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
1254
1255 SetLastError(0xdeadbeef);
1256 ret = WaitForSingleObject(modify_handle(signaled, 2), 0);
1257 ok(ret == WAIT_OBJECT_0, "expected WAIT_OBJECT_0, got %d\n", ret);
1258 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
1259
1260 SetLastError(0xdeadbeef);
1261 ret = WaitForSingleObject(modify_handle(signaled, 3), 0);
1262 ok(ret == WAIT_OBJECT_0, "expected WAIT_OBJECT_0, got %d\n", ret);
1263 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
1264
1265 /* pseudo handles are allowed in WaitForSingleObject and NtWaitForSingleObject */
1266 ret = WaitForSingleObject(GetCurrentProcess(), 100);
1267 ok(ret == WAIT_TIMEOUT, "expected WAIT_TIMEOUT, got %u\n", ret);
1268
1269 ret = WaitForSingleObject(GetCurrentThread(), 100);
1270 ok(ret == WAIT_TIMEOUT, "expected WAIT_TIMEOUT, got %u\n", ret);
1271
1272 timeout.QuadPart = -1000000;
1273 status = pNtWaitForSingleObject(GetCurrentProcess(), FALSE, &timeout);
1274 ok(status == STATUS_TIMEOUT, "expected STATUS_TIMEOUT, got %08x\n", status);
1275
1276 timeout.QuadPart = -1000000;
1277 status = pNtWaitForSingleObject(GetCurrentThread(), FALSE, &timeout);
1278 ok(status == STATUS_TIMEOUT, "expected STATUS_TIMEOUT, got %08x\n", status);
1279
1280 CloseHandle(signaled);
1281 CloseHandle(nonsignaled);
1282 }
1283
1284 static void test_WaitForMultipleObjects(void)
1285 {
1286 LARGE_INTEGER timeout;
1287 NTSTATUS status;
1288 DWORD r;
1289 int i;
1290 HANDLE maxevents[MAXIMUM_WAIT_OBJECTS];
1291
1292 /* create the maximum number of events and make sure
1293 * we can wait on that many */
1294 for (i=0; i<MAXIMUM_WAIT_OBJECTS; i++)
1295 {
1296 maxevents[i] = CreateEventW(NULL, i==0, TRUE, NULL);
1297 ok( maxevents[i] != 0, "should create enough events\n");
1298 }
1299
1300 /* a manual-reset event remains signaled, an auto-reset event is cleared */
1301 r = WaitForMultipleObjects(MAXIMUM_WAIT_OBJECTS, maxevents, FALSE, 0);
1302 ok( r == WAIT_OBJECT_0, "should signal lowest handle first, got %d\n", r);
1303 r = WaitForMultipleObjects(MAXIMUM_WAIT_OBJECTS, maxevents, FALSE, 0);
1304 ok( r == WAIT_OBJECT_0, "should signal handle #0 first, got %d\n", r);
1305 ok(ResetEvent(maxevents[0]), "ResetEvent\n");
1306 for (i=1; i<MAXIMUM_WAIT_OBJECTS; i++)
1307 {
1308 /* the lowest index is checked first and remaining events are untouched */
1309 r = WaitForMultipleObjects(MAXIMUM_WAIT_OBJECTS, maxevents, FALSE, 0);
1310 ok( r == WAIT_OBJECT_0+i, "should signal handle #%d first, got %d\n", i, r);
1311 }
1312
1313 /* run same test with Nt* call */
1314 for (i=0; i<MAXIMUM_WAIT_OBJECTS; i++)
1315 SetEvent(maxevents[i]);
1316
1317 /* a manual-reset event remains signaled, an auto-reset event is cleared */
1318 status = pNtWaitForMultipleObjects(MAXIMUM_WAIT_OBJECTS, maxevents, TRUE, FALSE, NULL);
1319 ok(status == STATUS_WAIT_0, "should signal lowest handle first, got %08x\n", status);
1320 status = pNtWaitForMultipleObjects(MAXIMUM_WAIT_OBJECTS, maxevents, TRUE, FALSE, NULL);
1321 ok(status == STATUS_WAIT_0, "should signal handle #0 first, got %08x\n", status);
1322 ok(ResetEvent(maxevents[0]), "ResetEvent\n");
1323 for (i=1; i<MAXIMUM_WAIT_OBJECTS; i++)
1324 {
1325 /* the lowest index is checked first and remaining events are untouched */
1326 status = pNtWaitForMultipleObjects(MAXIMUM_WAIT_OBJECTS, maxevents, TRUE, FALSE, NULL);
1327 ok(status == STATUS_WAIT_0 + i, "should signal handle #%d first, got %08x\n", i, status);
1328 }
1329
1330 for (i=0; i<MAXIMUM_WAIT_OBJECTS; i++)
1331 if (maxevents[i]) CloseHandle(maxevents[i]);
1332
1333 /* in contrast to WaitForSingleObject, pseudo handles are not allowed in
1334 * WaitForMultipleObjects and NtWaitForMultipleObjects */
1335 maxevents[0] = GetCurrentProcess();
1336 SetLastError(0xdeadbeef);
1337 r = WaitForMultipleObjects(1, maxevents, FALSE, 100);
1338 todo_wine ok(r == WAIT_FAILED, "expected WAIT_FAILED, got %u\n", r);
1339 todo_wine ok(GetLastError() == ERROR_INVALID_HANDLE,
1340 "expected ERROR_INVALID_HANDLE, got %u\n", GetLastError());
1341
1342 maxevents[0] = GetCurrentThread();
1343 SetLastError(0xdeadbeef);
1344 r = WaitForMultipleObjects(1, maxevents, FALSE, 100);
1345 todo_wine ok(r == WAIT_FAILED, "expected WAIT_FAILED, got %u\n", r);
1346 todo_wine ok(GetLastError() == ERROR_INVALID_HANDLE,
1347 "expected ERROR_INVALID_HANDLE, got %u\n", GetLastError());
1348
1349 timeout.QuadPart = -1000000;
1350 maxevents[0] = GetCurrentProcess();
1351 status = pNtWaitForMultipleObjects(1, maxevents, TRUE, FALSE, &timeout);
1352 todo_wine ok(status == STATUS_INVALID_HANDLE, "expected STATUS_INVALID_HANDLE, got %08x\n", status);
1353
1354 timeout.QuadPart = -1000000;
1355 maxevents[0] = GetCurrentThread();
1356 status = pNtWaitForMultipleObjects(1, maxevents, TRUE, FALSE, &timeout);
1357 todo_wine ok(status == STATUS_INVALID_HANDLE, "expected STATUS_INVALID_HANDLE, got %08x\n", status);
1358 }
1359
1360 static BOOL g_initcallback_ret, g_initcallback_called;
1361 static void *g_initctxt;
1362
1363 static BOOL CALLBACK initonce_callback(INIT_ONCE *initonce, void *parameter, void **ctxt)
1364 {
1365 g_initcallback_called = TRUE;
1366 /* zero bit set means here that initialization is taking place - initialization locked */
1367 ok(g_initctxt == *ctxt, "got wrong context value %p, expected %p\n", *ctxt, g_initctxt);
1368 ok(initonce->Ptr == (void*)0x1, "got %p\n", initonce->Ptr);
1369 ok(parameter == (void*)0xdeadbeef, "got wrong parameter\n");
1370 return g_initcallback_ret;
1371 }
1372
1373 static void test_initonce(void)
1374 {
1375 INIT_ONCE initonce;
1376 BOOL ret, pending;
1377
1378 if (!pInitOnceInitialize || !pInitOnceExecuteOnce)
1379 {
1380 win_skip("one-time initialization API not supported\n");
1381 return;
1382 }
1383
1384 /* blocking initialization with callback */
1385 initonce.Ptr = (void*)0xdeadbeef;
1386 pInitOnceInitialize(&initonce);
1387 ok(initonce.Ptr == NULL, "got %p\n", initonce.Ptr);
1388
1389 /* initialisation completed successfully */
1390 g_initcallback_ret = TRUE;
1391 g_initctxt = NULL;
1392 ret = pInitOnceExecuteOnce(&initonce, initonce_callback, (void*)0xdeadbeef, &g_initctxt);
1393 ok(ret, "wrong ret %d err %u\n", ret, GetLastError());
1394 ok(initonce.Ptr == (void*)0x2, "got %p\n", initonce.Ptr);
1395 ok(g_initctxt == NULL, "got %p\n", g_initctxt);
1396 ok(g_initcallback_called, "got %d\n", g_initcallback_called);
1397
1398 /* so it's been called already so won't be called again */
1399 g_initctxt = NULL;
1400 g_initcallback_called = FALSE;
1401 ret = pInitOnceExecuteOnce(&initonce, initonce_callback, (void*)0xdeadbeef, &g_initctxt);
1402 ok(ret, "wrong ret %d err %u\n", ret, GetLastError());
1403 ok(initonce.Ptr == (void*)0x2, "got %p\n", initonce.Ptr);
1404 ok(g_initctxt == NULL, "got %p\n", g_initctxt);
1405 ok(!g_initcallback_called, "got %d\n", g_initcallback_called);
1406
1407 pInitOnceInitialize(&initonce);
1408 g_initcallback_called = FALSE;
1409 /* 2 lower order bits should never be used, you'll get a crash in result */
1410 g_initctxt = (void*)0xFFFFFFF0;
1411 ret = pInitOnceExecuteOnce(&initonce, initonce_callback, (void*)0xdeadbeef, &g_initctxt);
1412 ok(ret, "wrong ret %d err %u\n", ret, GetLastError());
1413 ok(initonce.Ptr == (void*)0xFFFFFFF2, "got %p\n", initonce.Ptr);
1414 ok(g_initctxt == (void*)0xFFFFFFF0, "got %p\n", g_initctxt);
1415 ok(g_initcallback_called, "got %d\n", g_initcallback_called);
1416
1417 /* callback failed */
1418 g_initcallback_ret = FALSE;
1419 g_initcallback_called = FALSE;
1420 g_initctxt = NULL;
1421 pInitOnceInitialize(&initonce);
1422 SetLastError( 0xdeadbeef );
1423 ret = pInitOnceExecuteOnce(&initonce, initonce_callback, (void*)0xdeadbeef, &g_initctxt);
1424 ok(!ret && GetLastError() == 0xdeadbeef, "got wrong ret value %d err %u\n", ret, GetLastError());
1425 ok(initonce.Ptr == NULL, "got %p\n", initonce.Ptr);
1426 ok(g_initctxt == NULL, "got %p\n", g_initctxt);
1427 ok(g_initcallback_called, "got %d\n", g_initcallback_called);
1428
1429 /* blocking initialization without a callback */
1430 pInitOnceInitialize(&initonce);
1431 g_initctxt = NULL;
1432 pending = FALSE;
1433 ret = pInitOnceBeginInitialize(&initonce, 0, &pending, &g_initctxt);
1434 ok(ret, "wrong ret %d err %u\n", ret, GetLastError());
1435 ok(pending, "got %d\n", pending);
1436 ok(initonce.Ptr == (void*)1, "got %p\n", initonce.Ptr);
1437 ok(g_initctxt == NULL, "got %p\n", g_initctxt);
1438 /* another attempt to begin initialization with block a single thread */
1439
1440 g_initctxt = NULL;
1441 pending = 0xf;
1442 SetLastError( 0xdeadbeef );
1443 ret = pInitOnceBeginInitialize(&initonce, INIT_ONCE_CHECK_ONLY, &pending, &g_initctxt);
1444 ok(!ret && GetLastError() == ERROR_GEN_FAILURE, "wrong ret %d err %u\n", ret, GetLastError());
1445 ok(pending == 0xf, "got %d\n", pending);
1446 ok(initonce.Ptr == (void*)1, "got %p\n", initonce.Ptr);
1447 ok(g_initctxt == NULL, "got %p\n", g_initctxt);
1448
1449 g_initctxt = (void*)0xdeadbee0;
1450 SetLastError( 0xdeadbeef );
1451 ret = pInitOnceComplete(&initonce, INIT_ONCE_INIT_FAILED, g_initctxt);
1452 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "wrong ret %d err %u\n", ret, GetLastError());
1453 ok(initonce.Ptr == (void*)1, "got %p\n", initonce.Ptr);
1454
1455 /* once failed already */
1456 g_initctxt = (void*)0xdeadbee0;
1457 ret = pInitOnceComplete(&initonce, 0, g_initctxt);
1458 ok(ret, "wrong ret %d err %u\n", ret, GetLastError());
1459 ok(initonce.Ptr == (void*)0xdeadbee2, "got %p\n", initonce.Ptr);
1460
1461 pInitOnceInitialize(&initonce);
1462 SetLastError( 0xdeadbeef );
1463 ret = pInitOnceComplete(&initonce, INIT_ONCE_INIT_FAILED, NULL);
1464 ok(!ret && GetLastError() == ERROR_GEN_FAILURE, "wrong ret %d err %u\n", ret, GetLastError());
1465 ok(initonce.Ptr == NULL, "got %p\n", initonce.Ptr);
1466
1467 SetLastError( 0xdeadbeef );
1468 ret = pInitOnceComplete(&initonce, INIT_ONCE_INIT_FAILED | INIT_ONCE_ASYNC, NULL);
1469 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "wrong ret %d err %u\n", ret, GetLastError());
1470 ok(initonce.Ptr == NULL, "got %p\n", initonce.Ptr);
1471
1472 ret = pInitOnceBeginInitialize(&initonce, 0, &pending, &g_initctxt);
1473 ok(ret, "wrong ret %d err %u\n", ret, GetLastError());
1474 ok(pending, "got %d\n", pending);
1475 ok(initonce.Ptr == (void*)1, "got %p\n", initonce.Ptr);
1476
1477 SetLastError( 0xdeadbeef );
1478 ret = pInitOnceBeginInitialize(&initonce, INIT_ONCE_ASYNC, &pending, &g_initctxt);
1479 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "wrong ret %d err %u\n", ret, GetLastError());
1480
1481 SetLastError( 0xdeadbeef );
1482 ret = pInitOnceComplete(&initonce, INIT_ONCE_INIT_FAILED | INIT_ONCE_ASYNC, NULL);
1483 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "wrong ret %d err %u\n", ret, GetLastError());
1484 ok(initonce.Ptr == (void*)1, "got %p\n", initonce.Ptr);
1485
1486 SetLastError( 0xdeadbeef );
1487 ret = pInitOnceComplete(&initonce, 0, (void *)0xdeadbeef);
1488 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "wrong ret %d err %u\n", ret, GetLastError());
1489 ok(initonce.Ptr == (void*)1, "got %p\n", initonce.Ptr);
1490
1491 ret = pInitOnceComplete(&initonce, INIT_ONCE_INIT_FAILED, NULL);
1492 ok(ret, "wrong ret %d err %u\n", ret, GetLastError());
1493 ok(initonce.Ptr == NULL, "got %p\n", initonce.Ptr);
1494
1495 pInitOnceInitialize(&initonce);
1496 ret = pInitOnceBeginInitialize(&initonce, INIT_ONCE_ASYNC, &pending, &g_initctxt);
1497 ok(ret, "wrong ret %d err %u\n", ret, GetLastError());
1498 ok(pending, "got %d\n", pending);
1499 ok(initonce.Ptr == (void*)3, "got %p\n", initonce.Ptr);
1500
1501 SetLastError( 0xdeadbeef );
1502 ret = pInitOnceBeginInitialize(&initonce, 0, &pending, &g_initctxt);
1503 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "wrong ret %d err %u\n", ret, GetLastError());
1504
1505 ret = pInitOnceBeginInitialize(&initonce, INIT_ONCE_ASYNC, &pending, &g_initctxt);
1506 ok(ret, "wrong ret %d err %u\n", ret, GetLastError());
1507 ok(pending, "got %d\n", pending);
1508 ok(initonce.Ptr == (void*)3, "got %p\n", initonce.Ptr);
1509
1510 SetLastError( 0xdeadbeef );
1511 ret = pInitOnceComplete(&initonce, INIT_ONCE_INIT_FAILED, NULL);
1512 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "wrong ret %d err %u\n", ret, GetLastError());
1513 ok(initonce.Ptr == (void*)3, "got %p\n", initonce.Ptr);
1514
1515 SetLastError( 0xdeadbeef );
1516 ret = pInitOnceComplete(&initonce, INIT_ONCE_INIT_FAILED | INIT_ONCE_ASYNC, NULL);
1517 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "wrong ret %d err %u\n", ret, GetLastError());
1518 ok(initonce.Ptr == (void*)3, "got %p\n", initonce.Ptr);
1519
1520 SetLastError( 0xdeadbeef );
1521 ret = pInitOnceComplete(&initonce, INIT_ONCE_ASYNC, (void *)0xdeadbeef);
1522 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "wrong ret %d err %u\n", ret, GetLastError());
1523 ok(initonce.Ptr == (void*)3, "got %p\n", initonce.Ptr);
1524
1525 ret = pInitOnceComplete(&initonce, INIT_ONCE_ASYNC, (void *)0xdeadbee0);
1526 ok(ret, "wrong ret %d err %u\n", ret, GetLastError());
1527 ok(initonce.Ptr == (void*)0xdeadbee2, "got %p\n", initonce.Ptr);
1528
1529 SetLastError( 0xdeadbeef );
1530 ret = pInitOnceComplete(&initonce, INIT_ONCE_INIT_FAILED | INIT_ONCE_ASYNC, NULL);
1531 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "wrong ret %d err %u\n", ret, GetLastError());
1532 ok(initonce.Ptr == (void*)0xdeadbee2, "got %p\n", initonce.Ptr);
1533
1534 pInitOnceInitialize(&initonce);
1535 ret = pInitOnceBeginInitialize(&initonce, 0, &pending, &g_initctxt);
1536 ok(ret, "wrong ret %d err %u\n", ret, GetLastError());
1537 ok(pending, "got %d\n", pending);
1538 ok(initonce.Ptr == (void*)1, "got %p\n", initonce.Ptr);
1539
1540 /* test INIT_ONCE_CHECK_ONLY */
1541
1542 pInitOnceInitialize(&initonce);
1543 SetLastError( 0xdeadbeef );
1544 ret = pInitOnceBeginInitialize(&initonce, INIT_ONCE_CHECK_ONLY, &pending, &g_initctxt);
1545 ok(!ret && GetLastError() == ERROR_GEN_FAILURE, "wrong ret %d err %u\n", ret, GetLastError());
1546 SetLastError( 0xdeadbeef );
1547 ret = pInitOnceBeginInitialize(&initonce, INIT_ONCE_CHECK_ONLY|INIT_ONCE_ASYNC, &pending, &g_initctxt);
1548 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "wrong ret %d err %u\n", ret, GetLastError());
1549
1550 ret = pInitOnceBeginInitialize(&initonce, 0, &pending, &g_initctxt);
1551 ok(ret, "wrong ret %d err %u\n", ret, GetLastError());
1552 ok(pending, "got %d\n", pending);
1553 ok(initonce.Ptr == (void*)1, "got %p\n", initonce.Ptr);
1554
1555 SetLastError( 0xdeadbeef );
1556 ret = pInitOnceBeginInitialize(&initonce, INIT_ONCE_CHECK_ONLY, &pending, &g_initctxt);
1557 ok(!ret && GetLastError() == ERROR_GEN_FAILURE, "wrong ret %d err %u\n", ret, GetLastError());
1558 SetLastError( 0xdeadbeef );
1559 ret = pInitOnceBeginInitialize(&initonce, INIT_ONCE_CHECK_ONLY|INIT_ONCE_ASYNC, &pending, &g_initctxt);
1560 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "wrong ret %d err %u\n", ret, GetLastError());
1561
1562 ret = pInitOnceComplete(&initonce, 0, (void *)0xdeadbee0);
1563 ok(ret, "wrong ret %d err %u\n", ret, GetLastError());
1564 ok(initonce.Ptr == (void*)0xdeadbee2, "got %p\n", initonce.Ptr);
1565
1566 ret = pInitOnceBeginInitialize(&initonce, INIT_ONCE_CHECK_ONLY, &pending, &g_initctxt);
1567 ok(ret, "got wrong ret value %d err %u\n", ret, GetLastError());
1568 ok(!pending, "got %d\n", pending);
1569 ok(initonce.Ptr == (void*)0xdeadbee2, "got %p\n", initonce.Ptr);
1570 ok(g_initctxt == (void*)0xdeadbee0, "got %p\n", initonce.Ptr);
1571
1572 SetLastError( 0xdeadbeef );
1573 ret = pInitOnceBeginInitialize(&initonce, INIT_ONCE_CHECK_ONLY|INIT_ONCE_ASYNC, &pending, &g_initctxt);
1574 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "wrong ret %d err %u\n", ret, GetLastError());
1575
1576 pInitOnceInitialize(&initonce);
1577 ret = pInitOnceBeginInitialize(&initonce, INIT_ONCE_ASYNC, &pending, &g_initctxt);
1578 ok(ret, "wrong ret %d err %u\n", ret, GetLastError());
1579 ok(pending, "got %d\n", pending);
1580 ok(initonce.Ptr == (void*)3, "got %p\n", initonce.Ptr);
1581
1582 SetLastError( 0xdeadbeef );
1583 ret = pInitOnceBeginInitialize(&initonce, INIT_ONCE_CHECK_ONLY, &pending, &g_initctxt);
1584 ok(!ret && GetLastError() == ERROR_GEN_FAILURE, "wrong ret %d err %u\n", ret, GetLastError());
1585 SetLastError( 0xdeadbeef );
1586 ret = pInitOnceBeginInitialize(&initonce, INIT_ONCE_CHECK_ONLY|INIT_ONCE_ASYNC, &pending, &g_initctxt);
1587 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "wrong ret %d err %u\n", ret, GetLastError());
1588
1589 ret = pInitOnceComplete(&initonce, INIT_ONCE_ASYNC, (void *)0xdeadbee0);
1590 ok(ret, "wrong ret %d err %u\n", ret, GetLastError());
1591 ok(initonce.Ptr == (void*)0xdeadbee2, "got %p\n", initonce.Ptr);
1592
1593 ret = pInitOnceBeginInitialize(&initonce, INIT_ONCE_CHECK_ONLY, &pending, &g_initctxt);
1594 ok(ret, "got wrong ret value %d err %u\n", ret, GetLastError());
1595 ok(!pending, "got %d\n", pending);
1596 ok(initonce.Ptr == (void*)0xdeadbee2, "got %p\n", initonce.Ptr);
1597 ok(g_initctxt == (void*)0xdeadbee0, "got %p\n", initonce.Ptr);
1598
1599 SetLastError( 0xdeadbeef );
1600 ret = pInitOnceBeginInitialize(&initonce, INIT_ONCE_CHECK_ONLY|INIT_ONCE_ASYNC, &pending, &g_initctxt);
1601 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "wrong ret %d err %u\n", ret, GetLastError());
1602 }
1603
1604 static CONDITION_VARIABLE buffernotempty = CONDITION_VARIABLE_INIT;
1605 static CONDITION_VARIABLE buffernotfull = CONDITION_VARIABLE_INIT;
1606 static CRITICAL_SECTION buffercrit;
1607 static BOOL condvar_stop = FALSE, condvar_sleeperr = FALSE;
1608 static LONG bufferlen,totalproduced,totalconsumed;
1609 static LONG condvar_producer_sleepcnt,condvar_consumer_sleepcnt;
1610
1611 #define BUFFER_SIZE 5
1612
1613 static DWORD WINAPI condvar_producer(LPVOID x) {
1614 DWORD sleepinterval = 5;
1615
1616 while (1) {
1617 Sleep(sleepinterval);
1618 if (sleepinterval > 1)
1619 sleepinterval -= 1;
1620
1621 EnterCriticalSection(&buffercrit);
1622 while ((bufferlen == BUFFER_SIZE) && !condvar_stop) {
1623 condvar_producer_sleepcnt++;
1624 if (!pSleepConditionVariableCS(&buffernotfull, &buffercrit, sleepinterval)) {
1625 if (GetLastError() != ERROR_TIMEOUT)
1626 condvar_sleeperr = TRUE;
1627 }
1628 }
1629 if (condvar_stop) {
1630 LeaveCriticalSection(&buffercrit);
1631 break;
1632 }
1633 bufferlen++;
1634 totalproduced++;
1635 LeaveCriticalSection(&buffercrit);
1636 pWakeConditionVariable(&buffernotempty);
1637 }
1638 return 0;
1639 }
1640
1641 static DWORD WINAPI condvar_consumer(LPVOID x) {
1642 DWORD *cnt = (DWORD*)x;
1643 DWORD sleepinterval = 1;
1644
1645 while (1) {
1646 EnterCriticalSection(&buffercrit);
1647 while ((bufferlen == 0) && !condvar_stop) {
1648 condvar_consumer_sleepcnt++;
1649 if (!pSleepConditionVariableCS (&buffernotempty, &buffercrit, sleepinterval)) {
1650 if (GetLastError() != ERROR_TIMEOUT)
1651 condvar_sleeperr = TRUE;
1652 }
1653 }
1654 if (condvar_stop && (bufferlen == 0)) {
1655 LeaveCriticalSection(&buffercrit);
1656 break;
1657 }
1658 bufferlen--;
1659 totalconsumed++;
1660 (*cnt)++;
1661 LeaveCriticalSection(&buffercrit);
1662 pWakeConditionVariable(&buffernotfull);
1663 Sleep(sleepinterval);
1664 if (sleepinterval < 5) sleepinterval += 1;
1665 }
1666 return 0;
1667 }
1668
1669 static void test_condvars_consumer_producer(void)
1670 {
1671 HANDLE hp1,hp2,hp3,hc1,hc2,hc3;
1672 DWORD dummy;
1673 DWORD cnt1,cnt2,cnt3;
1674
1675 if (!pInitializeConditionVariable) {
1676 /* function is not yet in XP, only in newer Windows */
1677 win_skip("no condition variable support.\n");
1678 return;
1679 }
1680
1681 /* Implement a producer / consumer scheme with non-full / non-empty triggers */
1682
1683 /* If we have static initialized condition variables, InitializeConditionVariable
1684 * is not strictly necessary.
1685 * pInitializeConditionVariable(&buffernotfull);
1686 */
1687 pInitializeConditionVariable(&buffernotempty);
1688 InitializeCriticalSection(&buffercrit);
1689
1690 /* Larger Test: consumer/producer example */
1691
1692 bufferlen = totalproduced = totalconsumed = cnt1 = cnt2 = cnt3 = 0;
1693
1694 hp1 = CreateThread(NULL, 0, condvar_producer, NULL, 0, &dummy);
1695 hp2 = CreateThread(NULL, 0, condvar_producer, NULL, 0, &dummy);
1696 hp3 = CreateThread(NULL, 0, condvar_producer, NULL, 0, &dummy);
1697 hc1 = CreateThread(NULL, 0, condvar_consumer, (PVOID)&cnt1, 0, &dummy);
1698 hc2 = CreateThread(NULL, 0, condvar_consumer, (PVOID)&cnt2, 0, &dummy);
1699 hc3 = CreateThread(NULL, 0, condvar_consumer, (PVOID)&cnt3, 0, &dummy);
1700
1701 /* Limit run to 0.5 seconds. */
1702 Sleep(500);
1703
1704 /* tear down start */
1705 condvar_stop = TRUE;
1706
1707 /* final wake up call */
1708 pWakeAllConditionVariable (&buffernotfull);
1709 pWakeAllConditionVariable (&buffernotempty);
1710
1711 /* (mostly an implementation detail)
1712 * ok(buffernotfull.Ptr == NULL, "buffernotfull.Ptr is %p\n", buffernotfull.Ptr);
1713 */
1714
1715 WaitForSingleObject(hp1, 1000);
1716 WaitForSingleObject(hp2, 1000);
1717 WaitForSingleObject(hp3, 1000);
1718 WaitForSingleObject(hc1, 1000);
1719 WaitForSingleObject(hc2, 1000);
1720 WaitForSingleObject(hc3, 1000);
1721
1722 ok(totalconsumed == totalproduced,
1723 "consumed %d != produced %d\n", totalconsumed, totalproduced);
1724 ok (!condvar_sleeperr, "error occurred during SleepConditionVariableCS\n");
1725
1726 /* Checking cnt1 - cnt2 for non-0 would be not good, the case where
1727 * one consumer does not get anything to do is possible. */
1728 trace("produced %d, c1 %d, c2 %d, c3 %d\n", totalproduced, cnt1, cnt2, cnt3);
1729 /* The sleeps of the producer or consumer should not go above 100* produced count,
1730 * otherwise the implementation does not sleep correctly. But yet again, this is
1731 * not hard defined. */
1732 trace("producer sleep %d, consumer sleep %d\n", condvar_producer_sleepcnt, condvar_consumer_sleepcnt);
1733 }
1734
1735 /* Sample test for some sequence of events happening, sequenced using "condvar_seq" */
1736 static DWORD condvar_seq = 0;
1737 static CONDITION_VARIABLE condvar_base = CONDITION_VARIABLE_INIT;
1738 static CRITICAL_SECTION condvar_crit;
1739 static SRWLOCK condvar_srwlock;
1740
1741 /* Sequence of wake/sleep to check boundary conditions:
1742 * 0: init
1743 * 1: producer emits a WakeConditionVariable without consumer waiting.
1744 * 2: consumer sleeps without a wake expecting timeout
1745 * 3: producer emits a WakeAllConditionVariable without consumer waiting.
1746 * 4: consumer sleeps without a wake expecting timeout
1747 * 5: a wake is handed to a SleepConditionVariableCS
1748 * 6: a wakeall is handed to a SleepConditionVariableCS
1749 * 7: sleep after above should timeout
1750 * 8: wake with crit section locked into the sleep timeout
1751 *
1752 * the following tests will only be executed if InitializeSRWLock is available
1753 *
1754 * 9: producer (exclusive) wakes up consumer (exclusive)
1755 * 10: producer (exclusive) wakes up consumer (shared)
1756 * 11: producer (shared) wakes up consumer (exclusive)
1757 * 12: producer (shared) wakes up consumer (shared)
1758 * 13: end
1759 */
1760 static DWORD WINAPI condvar_base_producer(LPVOID x) {
1761 while (condvar_seq < 1) Sleep(1);
1762
1763 pWakeConditionVariable (&condvar_base);
1764 condvar_seq = 2;
1765
1766 while (condvar_seq < 3) Sleep(1);
1767 pWakeAllConditionVariable (&condvar_base);
1768 condvar_seq = 4;
1769
1770 while (condvar_seq < 5) Sleep(1);
1771 EnterCriticalSection (&condvar_crit);
1772 pWakeConditionVariable (&condvar_base);
1773 LeaveCriticalSection (&condvar_crit);
1774 while (condvar_seq < 6) Sleep(1);
1775 EnterCriticalSection (&condvar_crit);
1776 pWakeAllConditionVariable (&condvar_base);
1777 LeaveCriticalSection (&condvar_crit);
1778
1779 while (condvar_seq < 8) Sleep(1);
1780 EnterCriticalSection (&condvar_crit);
1781 pWakeConditionVariable (&condvar_base);
1782 Sleep(50);
1783 LeaveCriticalSection (&condvar_crit);
1784
1785 /* skip over remaining tests if InitializeSRWLock is not available */
1786 if (!pInitializeSRWLock)
1787 return 0;
1788
1789 while (condvar_seq < 9) Sleep(1);
1790 pAcquireSRWLockExclusive(&condvar_srwlock);
1791 pWakeConditionVariable(&condvar_base);
1792 pReleaseSRWLockExclusive(&condvar_srwlock);
1793
1794 while (condvar_seq < 10) Sleep(1);
1795 pAcquireSRWLockExclusive(&condvar_srwlock);
1796 pWakeConditionVariable(&condvar_base);
1797 pReleaseSRWLockExclusive(&condvar_srwlock);
1798
1799 while (condvar_seq < 11) Sleep(1);
1800 pAcquireSRWLockShared(&condvar_srwlock);
1801 pWakeConditionVariable(&condvar_base);
1802 pReleaseSRWLockShared(&condvar_srwlock);
1803
1804 while (condvar_seq < 12) Sleep(1);
1805 Sleep(50); /* ensure that consumer waits for cond variable */
1806 pAcquireSRWLockShared(&condvar_srwlock);
1807 pWakeConditionVariable(&condvar_base);
1808 pReleaseSRWLockShared(&condvar_srwlock);
1809
1810 return 0;
1811 }
1812
1813 static DWORD WINAPI condvar_base_consumer(LPVOID x) {
1814 BOOL ret;
1815
1816 while (condvar_seq < 2) Sleep(1);
1817
1818 /* wake was emitted, but we were not sleeping */
1819 EnterCriticalSection (&condvar_crit);
1820 ret = pSleepConditionVariableCS(&condvar_base, &condvar_crit, 10);
1821 LeaveCriticalSection (&condvar_crit);
1822 ok (!ret, "SleepConditionVariableCS should return FALSE on out of band wake\n");
1823 ok (GetLastError() == ERROR_TIMEOUT, "SleepConditionVariableCS should return ERROR_TIMEOUT on out of band wake, not %d\n", GetLastError());
1824
1825 condvar_seq = 3;
1826 while (condvar_seq < 4) Sleep(1);
1827
1828 /* wake all was emitted, but we were not sleeping */
1829 EnterCriticalSection (&condvar_crit);
1830 ret = pSleepConditionVariableCS(&condvar_base, &condvar_crit, 10);
1831 LeaveCriticalSection (&condvar_crit);
1832 ok (!ret, "SleepConditionVariableCS should return FALSE on out of band wake\n");
1833 ok (GetLastError() == ERROR_TIMEOUT, "SleepConditionVariableCS should return ERROR_TIMEOUT on out of band wake, not %d\n", GetLastError());
1834
1835 EnterCriticalSection (&condvar_crit);
1836 condvar_seq = 5;
1837 ret = pSleepConditionVariableCS(&condvar_base, &condvar_crit, 200);
1838 LeaveCriticalSection (&condvar_crit);
1839 ok (ret, "SleepConditionVariableCS should return TRUE on good wake\n");
1840
1841 EnterCriticalSection (&condvar_crit);
1842 condvar_seq = 6;
1843 ret = pSleepConditionVariableCS(&condvar_base, &condvar_crit, 200);
1844 LeaveCriticalSection (&condvar_crit);
1845 ok (ret, "SleepConditionVariableCS should return TRUE on good wakeall\n");
1846 condvar_seq = 7;
1847
1848 EnterCriticalSection (&condvar_crit);
1849 ret = pSleepConditionVariableCS(&condvar_base, &condvar_crit, 10);
1850 LeaveCriticalSection (&condvar_crit);
1851 ok (!ret, "SleepConditionVariableCS should return FALSE on out of band wake\n");
1852 ok (GetLastError() == ERROR_TIMEOUT, "SleepConditionVariableCS should return ERROR_TIMEOUT on out of band wake, not %d\n", GetLastError());
1853
1854 EnterCriticalSection (&condvar_crit);
1855 condvar_seq = 8;
1856 ret = pSleepConditionVariableCS(&condvar_base, &condvar_crit, 20);
1857 LeaveCriticalSection (&condvar_crit);
1858 ok (ret, "SleepConditionVariableCS should still return TRUE on crit unlock delay\n");
1859
1860 /* skip over remaining tests if InitializeSRWLock is not available */
1861 if (!pInitializeSRWLock)
1862 {
1863 win_skip("no srw lock support.\n");
1864 condvar_seq = 13; /* end */
1865 return 0;
1866 }
1867
1868 pAcquireSRWLockExclusive(&condvar_srwlock);
1869 condvar_seq = 9;
1870 ret = pSleepConditionVariableSRW(&condvar_base, &condvar_srwlock, 200, 0);
1871 pReleaseSRWLockExclusive(&condvar_srwlock);
1872 ok (ret, "pSleepConditionVariableSRW should return TRUE on good wake\n");
1873
1874 pAcquireSRWLockShared(&condvar_srwlock);
1875 condvar_seq = 10;
1876 ret = pSleepConditionVariableSRW(&condvar_base, &condvar_srwlock, 200, CONDITION_VARIABLE_LOCKMODE_SHARED);
1877 pReleaseSRWLockShared(&condvar_srwlock);
1878 ok (ret, "pSleepConditionVariableSRW should return TRUE on good wake\n");
1879
1880 pAcquireSRWLockExclusive(&condvar_srwlock);
1881 condvar_seq = 11;
1882 ret = pSleepConditionVariableSRW(&condvar_base, &condvar_srwlock, 200, 0);
1883 pReleaseSRWLockExclusive(&condvar_srwlock);
1884 ok (ret, "pSleepConditionVariableSRW should return TRUE on good wake\n");
1885
1886 pAcquireSRWLockShared(&condvar_srwlock);
1887 condvar_seq = 12;
1888 ret = pSleepConditionVariableSRW(&condvar_base, &condvar_srwlock, 200, CONDITION_VARIABLE_LOCKMODE_SHARED);
1889 pReleaseSRWLockShared(&condvar_srwlock);
1890 ok (ret, "pSleepConditionVariableSRW should return TRUE on good wake\n");
1891
1892 condvar_seq = 13;
1893 return 0;
1894 }
1895
1896 static void test_condvars_base(void) {
1897 HANDLE hp, hc;
1898 DWORD dummy;
1899 BOOL ret;
1900
1901
1902 if (!pInitializeConditionVariable) {
1903 /* function is not yet in XP, only in newer Windows */
1904 win_skip("no condition variable support.\n");
1905 return;
1906 }
1907
1908 InitializeCriticalSection (&condvar_crit);
1909
1910 if (pInitializeSRWLock)
1911 pInitializeSRWLock(&condvar_srwlock);
1912
1913 EnterCriticalSection (&condvar_crit);
1914 ret = pSleepConditionVariableCS(&condvar_base, &condvar_crit, 10);
1915 LeaveCriticalSection (&condvar_crit);
1916
1917 ok (!ret, "SleepConditionVariableCS should return FALSE on untriggered condvar\n");
1918 ok (GetLastError() == ERROR_TIMEOUT, "SleepConditionVariableCS should return ERROR_TIMEOUT on untriggered condvar, not %d\n", GetLastError());
1919
1920 if (pInitializeSRWLock)
1921 {
1922 pAcquireSRWLockExclusive(&condvar_srwlock);
1923 ret = pSleepConditionVariableSRW(&condvar_base, &condvar_srwlock, 10, 0);
1924 pReleaseSRWLockExclusive(&condvar_srwlock);
1925
1926 ok(!ret, "SleepConditionVariableSRW should return FALSE on untriggered condvar\n");
1927 ok(GetLastError() == ERROR_TIMEOUT, "SleepConditionVariableSRW should return ERROR_TIMEOUT on untriggered condvar, not %d\n", GetLastError());
1928
1929 pAcquireSRWLockShared(&condvar_srwlock);
1930 ret = pSleepConditionVariableSRW(&condvar_base, &condvar_srwlock, 10, CONDITION_VARIABLE_LOCKMODE_SHARED);
1931 pReleaseSRWLockShared(&condvar_srwlock);
1932
1933 ok(!ret, "SleepConditionVariableSRW should return FALSE on untriggered condvar\n");
1934 ok(GetLastError() == ERROR_TIMEOUT, "SleepConditionVariableSRW should return ERROR_TIMEOUT on untriggered condvar, not %d\n", GetLastError());
1935 }
1936
1937
1938 hp = CreateThread(NULL, 0, condvar_base_producer, NULL, 0, &dummy);
1939 hc = CreateThread(NULL, 0, condvar_base_consumer, NULL, 0, &dummy);
1940
1941 condvar_seq = 1; /* go */
1942
1943 while (condvar_seq < 9)
1944 Sleep (5);
1945 WaitForSingleObject(hp, 100);
1946 WaitForSingleObject(hc, 100);
1947 }
1948
1949 static LONG srwlock_seq = 0;
1950 static SRWLOCK srwlock_base;
1951 static struct
1952 {
1953 LONG wrong_execution_order;
1954 LONG samethread_excl_excl;
1955 LONG samethread_excl_shared;
1956 LONG samethread_shared_excl;
1957 LONG multithread_excl_excl;
1958 LONG excl_not_preferred;
1959 LONG trylock_excl;
1960 LONG trylock_shared;
1961 } srwlock_base_errors;
1962
1963 /* Sequence of acquire/release to check boundary conditions:
1964 * 0: init
1965 *
1966 * 1: thread2 acquires an exclusive lock and tries to acquire a second exclusive lock
1967 * 2: thread1 expects a deadlock and releases the waiting lock
1968 * thread2 releases the lock again
1969 *
1970 * 3: thread2 acquires an exclusive lock and tries to acquire a shared lock
1971 * 4: thread1 expects a deadlock and releases the waiting lock
1972 * thread2 releases the lock again
1973 *
1974 * 5: thread2 acquires a shared lock and tries to acquire an exclusive lock
1975 * 6: thread1 expects a deadlock and releases the waiting lock
1976 * thread2 releases the lock again
1977 *
1978 * 7: thread2 acquires and releases two nested shared locks
1979 *
1980 * 8: thread1 acquires an exclusive lock
1981 * 9: thread2 tries to acquire the exclusive lock, too
1982 * thread1 releases the exclusive lock again
1983 * 10: thread2 enters the exclusive lock and leaves it immediately again
1984 *
1985 * 11: thread1 acquires a shared lock
1986 * 12: thread2 acquires and releases a shared lock
1987 * thread1 releases the lock again
1988 *
1989 * 13: thread1 acquires a shared lock
1990 * 14: thread2 tries to acquire an exclusive lock
1991 * 15: thread3 tries to acquire a shared lock
1992 * 16: thread1 releases the shared lock
1993 * 17: thread2 wakes up and releases the exclusive lock
1994 * 18: thread3 wakes up and releases the shared lock
1995 *
1996 * the following tests will only be executed if TryAcquireSRWLock* is available
1997 *
1998 * 19: thread1 calls TryAcquireSRWLockExclusive which should return TRUE
1999 * thread1 checks the result of recursive calls to TryAcquireSRWLock*
2000 * thread1 releases the exclusive lock
2001 *
2002 * thread1 calls TryAcquireSRWLockShared which should return TRUE
2003 * thread1 checks the result of recursive calls to TryAcquireSRWLock*
2004 * thread1 releases the shared lock
2005 *
2006 * thread1 acquires an exclusive lock
2007 * 20: thread2 calls TryAcquireSRWLockShared which should return FALSE
2008 * thread2 calls TryAcquireSRWLockExclusive which should return FALSE
2009 * 21: thread1 releases the exclusive lock
2010 *
2011 * thread1 acquires an shared lock
2012 * 22: thread2 calls TryAcquireSRWLockShared which should return TRUE
2013 * thread2 calls TryAcquireSRWLockExclusive which should return FALSE
2014 * 23: thread1 releases the shared lock
2015 *
2016 * thread1 acquires a shared lock and tries to acquire an exclusive lock
2017 * 24: thread2 calls TryAcquireSRWLockShared which should return FALSE
2018 * thread2 calls TryAcquireSRWLockExclusive which should return FALSE
2019 * 25: thread1 releases the exclusive lock
2020 *
2021 * thread1 acquires two shared locks
2022 * 26: thread2 calls TryAcquireSRWLockShared which should return TRUE
2023 * thread2 calls TryAcquireSRWLockExclusive which should return FALSE
2024 * 27: thread1 releases one shared lock
2025 * 28: thread2 calls TryAcquireSRWLockShared which should return TRUE
2026 * thread2 calls TryAcquireSRWLockExclusive which should return FALSE
2027 * 29: thread1 releases the second shared lock
2028 * 30: thread2 calls TryAcquireSRWLockShared which should return TRUE
2029 * thread2 calls TryAcquireSRWLockExclusive which should return TRUE
2030 *
2031 * 31: end
2032 */
2033
2034 static DWORD WINAPI srwlock_base_thread1(LPVOID x)
2035 {
2036 /* seq 2 */
2037 while (srwlock_seq < 2) Sleep(1);
2038 Sleep(100);
2039 if (InterlockedIncrement(&srwlock_seq) != 3)
2040 InterlockedIncrement(&srwlock_base_errors.samethread_excl_excl);
2041 pReleaseSRWLockExclusive(&srwlock_base);
2042
2043 /* seq 4 */
2044 while (srwlock_seq < 4) Sleep(1);
2045 Sleep(100);
2046 if (InterlockedIncrement(&srwlock_seq) != 5)
2047 InterlockedIncrement(&srwlock_base_errors.samethread_excl_shared);
2048 pReleaseSRWLockExclusive(&srwlock_base);
2049
2050 /* seq 6 */
2051 while (srwlock_seq < 6) Sleep(1);
2052 Sleep(100);
2053 if (InterlockedIncrement(&srwlock_seq) != 7)
2054 InterlockedIncrement(&srwlock_base_errors.samethread_shared_excl);
2055 pReleaseSRWLockShared(&srwlock_base);
2056
2057 /* seq 8 */
2058 while (srwlock_seq < 8) Sleep(1);
2059 pAcquireSRWLockExclusive(&srwlock_base);
2060 if (InterlockedIncrement(&srwlock_seq) != 9)
2061 InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
2062 Sleep(100);
2063 if (InterlockedIncrement(&srwlock_seq) != 10)
2064 InterlockedIncrement(&srwlock_base_errors.multithread_excl_excl);
2065 pReleaseSRWLockExclusive(&srwlock_base);
2066
2067 /* seq 11 */
2068 while (srwlock_seq < 11) Sleep(1);
2069 pAcquireSRWLockShared(&srwlock_base);
2070 if (InterlockedIncrement(&srwlock_seq) != 12)
2071 InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
2072
2073 /* seq 13 */
2074 while (srwlock_seq < 13) Sleep(1);
2075 pReleaseSRWLockShared(&srwlock_base);
2076 pAcquireSRWLockShared(&srwlock_base);
2077 if (InterlockedIncrement(&srwlock_seq) != 14)
2078 InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
2079
2080 /* seq 16 */
2081 while (srwlock_seq < 16) Sleep(1);
2082 Sleep(50); /* ensure that both the exclusive and shared access thread are queued */
2083 if (InterlockedIncrement(&srwlock_seq) != 17)
2084 InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
2085 pReleaseSRWLockShared(&srwlock_base);
2086
2087 /* skip over remaining tests if TryAcquireSRWLock* is not available */
2088 if (!pTryAcquireSRWLockExclusive)
2089 return 0;
2090
2091 /* seq 19 */
2092 while (srwlock_seq < 19) Sleep(1);
2093 if (pTryAcquireSRWLockExclusive(&srwlock_base))
2094 {
2095 if (pTryAcquireSRWLockShared(&srwlock_base))
2096 InterlockedIncrement(&srwlock_base_errors.trylock_shared);
2097 if (pTryAcquireSRWLockExclusive(&srwlock_base))
2098 InterlockedIncrement(&srwlock_base_errors.trylock_excl);
2099 pReleaseSRWLockExclusive(&srwlock_base);
2100 }
2101 else
2102 InterlockedIncrement(&srwlock_base_errors.trylock_excl);
2103
2104 if (pTryAcquireSRWLockShared(&srwlock_base))
2105 {
2106 if (pTryAcquireSRWLockShared(&srwlock_base))
2107 pReleaseSRWLockShared(&srwlock_base);
2108 else
2109 InterlockedIncrement(&srwlock_base_errors.trylock_shared);
2110 if (pTryAcquireSRWLockExclusive(&srwlock_base))
2111 InterlockedIncrement(&srwlock_base_errors.trylock_excl);
2112 pReleaseSRWLockShared(&srwlock_base);
2113 }
2114 else
2115 InterlockedIncrement(&srwlock_base_errors.trylock_shared);
2116
2117 pAcquireSRWLockExclusive(&srwlock_base);
2118 if (InterlockedIncrement(&srwlock_seq) != 20)
2119 InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
2120
2121 /* seq 21 */
2122 while (srwlock_seq < 21) Sleep(1);
2123 pReleaseSRWLockExclusive(&srwlock_base);
2124 pAcquireSRWLockShared(&srwlock_base);
2125 if (InterlockedIncrement(&srwlock_seq) != 22)
2126 InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
2127
2128 /* seq 23 */
2129 while (srwlock_seq < 23) Sleep(1);
2130 pReleaseSRWLockShared(&srwlock_base);
2131 pAcquireSRWLockShared(&srwlock_base);
2132 if (InterlockedIncrement(&srwlock_seq) != 24)
2133 InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
2134
2135 /* seq 25 */
2136 pAcquireSRWLockExclusive(&srwlock_base);
2137 if (srwlock_seq != 25)
2138 InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
2139 pReleaseSRWLockExclusive(&srwlock_base);
2140
2141 pAcquireSRWLockShared(&srwlock_base);
2142 pAcquireSRWLockShared(&srwlock_base);
2143 if (InterlockedIncrement(&srwlock_seq) != 26)
2144 InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
2145
2146 /* seq 27 */
2147 while (srwlock_seq < 27) Sleep(1);
2148 pReleaseSRWLockShared(&srwlock_base);
2149 if (InterlockedIncrement(&srwlock_seq) != 28)
2150 InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
2151
2152 /* seq 29 */
2153 while (srwlock_seq < 29) Sleep(1);
2154 pReleaseSRWLockShared(&srwlock_base);
2155 if (InterlockedIncrement(&srwlock_seq) != 30)
2156 InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
2157
2158 return 0;
2159 }
2160
2161 static DWORD WINAPI srwlock_base_thread2(LPVOID x)
2162 {
2163 /* seq 1 */
2164 while (srwlock_seq < 1) Sleep(1);
2165 pAcquireSRWLockExclusive(&srwlock_base);
2166 if (InterlockedIncrement(&srwlock_seq) != 2)
2167 InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
2168
2169 /* seq 3 */
2170 pAcquireSRWLockExclusive(&srwlock_base);
2171 if (srwlock_seq != 3)
2172 InterlockedIncrement(&srwlock_base_errors.samethread_excl_excl);
2173 pReleaseSRWLockExclusive(&srwlock_base);
2174 pAcquireSRWLockExclusive(&srwlock_base);
2175 if (InterlockedIncrement(&srwlock_seq) != 4)
2176 InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
2177
2178 /* seq 5 */
2179 pAcquireSRWLockShared(&srwlock_base);
2180 if (srwlock_seq != 5)
2181 InterlockedIncrement(&srwlock_base_errors.samethread_excl_shared);
2182 pReleaseSRWLockShared(&srwlock_base);
2183 pAcquireSRWLockShared(&srwlock_base);
2184 if (InterlockedIncrement(&srwlock_seq) != 6)
2185 InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
2186
2187 /* seq 7 */
2188 pAcquireSRWLockExclusive(&srwlock_base);
2189 if (srwlock_seq != 7)
2190 InterlockedIncrement(&srwlock_base_errors.samethread_shared_excl);
2191 pReleaseSRWLockExclusive(&srwlock_base);
2192 pAcquireSRWLockShared(&srwlock_base);
2193 pAcquireSRWLockShared(&srwlock_base);
2194 pReleaseSRWLockShared(&srwlock_base);
2195 pReleaseSRWLockShared(&srwlock_base);
2196 if (InterlockedIncrement(&srwlock_seq) != 8)
2197 InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
2198
2199 /* seq 9, 10 */
2200 while (srwlock_seq < 9) Sleep(1);
2201 pAcquireSRWLockExclusive(&srwlock_base);
2202 if (srwlock_seq != 10)
2203 InterlockedIncrement(&srwlock_base_errors.multithread_excl_excl);
2204 pReleaseSRWLockExclusive(&srwlock_base);
2205 if (InterlockedIncrement(&srwlock_seq) != 11)
2206 InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
2207
2208 /* seq 12 */
2209 while (srwlock_seq < 12) Sleep(1);
2210 pAcquireSRWLockShared(&srwlock_base);
2211 pReleaseSRWLockShared(&srwlock_base);
2212 if (InterlockedIncrement(&srwlock_seq) != 13)
2213 InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
2214
2215 /* seq 14 */
2216 while (srwlock_seq < 14) Sleep(1);
2217 if (InterlockedIncrement(&srwlock_seq) != 15)
2218 InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
2219
2220 /* seq 17 */
2221 pAcquireSRWLockExclusive(&srwlock_base);
2222 if (srwlock_seq != 17)
2223 InterlockedIncrement(&srwlock_base_errors.excl_not_preferred);
2224 if (InterlockedIncrement(&srwlock_seq) != 18)
2225 InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
2226 pReleaseSRWLockExclusive(&srwlock_base);
2227
2228 /* skip over remaining tests if TryAcquireSRWLock* is not available */
2229 if (!pTryAcquireSRWLockExclusive)
2230 return 0;
2231
2232 /* seq 20 */
2233 while (srwlock_seq < 20) Sleep(1);
2234 if (pTryAcquireSRWLockShared(&srwlock_base))
2235 InterlockedIncrement(&srwlock_base_errors.trylock_shared);
2236 if (pTryAcquireSRWLockExclusive(&srwlock_base))
2237 InterlockedIncrement(&srwlock_base_errors.trylock_excl);
2238 if (InterlockedIncrement(&srwlock_seq) != 21)
2239 InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
2240
2241 /* seq 22 */
2242 while (srwlock_seq < 22) Sleep(1);
2243 if (pTryAcquireSRWLockShared(&srwlock_base))
2244 pReleaseSRWLockShared(&srwlock_base);
2245 else
2246 InterlockedIncrement(&srwlock_base_errors.trylock_shared);
2247 if (pTryAcquireSRWLockExclusive(&srwlock_base))
2248 InterlockedIncrement(&srwlock_base_errors.trylock_excl);
2249 if (InterlockedIncrement(&srwlock_seq) != 23)
2250 InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
2251
2252 /* seq 24 */
2253 while (srwlock_seq < 24) Sleep(1);
2254 Sleep(50); /* ensure that exclusive access request is queued */
2255 if (pTryAcquireSRWLockShared(&srwlock_base))
2256 {
2257 pReleaseSRWLockShared(&srwlock_base);
2258 InterlockedIncrement(&srwlock_base_errors.excl_not_preferred);
2259 }
2260 if (pTryAcquireSRWLockExclusive(&srwlock_base))
2261 InterlockedIncrement(&srwlock_base_errors.trylock_excl);
2262 if (InterlockedIncrement(&srwlock_seq) != 25)
2263 InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
2264 pReleaseSRWLockShared(&srwlock_base);
2265
2266 /* seq 26 */
2267 while (srwlock_seq < 26) Sleep(1);
2268 if (pTryAcquireSRWLockShared(&srwlock_base))
2269 pReleaseSRWLockShared(&srwlock_base);
2270 else
2271 InterlockedIncrement(&srwlock_base_errors.trylock_shared);
2272 if (pTryAcquireSRWLockExclusive(&srwlock_base))
2273 InterlockedIncrement(&srwlock_base_errors.trylock_excl);
2274 if (InterlockedIncrement(&srwlock_seq) != 27)
2275 InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
2276
2277 /* seq 28 */
2278 while (srwlock_seq < 28) Sleep(1);
2279 if (pTryAcquireSRWLockShared(&srwlock_base))
2280 pReleaseSRWLockShared(&srwlock_base);
2281 else
2282 InterlockedIncrement(&srwlock_base_errors.trylock_shared);
2283 if (pTryAcquireSRWLockExclusive(&srwlock_base))
2284 InterlockedIncrement(&srwlock_base_errors.trylock_excl);
2285 if (InterlockedIncrement(&srwlock_seq) != 29)
2286 InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
2287
2288 /* seq 30 */
2289 while (srwlock_seq < 30) Sleep(1);
2290 if (pTryAcquireSRWLockShared(&srwlock_base))
2291 pReleaseSRWLockShared(&srwlock_base);
2292 else
2293 InterlockedIncrement(&srwlock_base_errors.trylock_shared);
2294 if (pTryAcquireSRWLockExclusive(&srwlock_base))
2295 pReleaseSRWLockExclusive(&srwlock_base);
2296 else
2297 InterlockedIncrement(&srwlock_base_errors.trylock_excl);
2298 if (InterlockedIncrement(&srwlock_seq) != 31)
2299 InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
2300
2301 return 0;
2302 }
2303
2304 static DWORD WINAPI srwlock_base_thread3(LPVOID x)
2305 {
2306 /* seq 15 */
2307 while (srwlock_seq < 15) Sleep(1);
2308 Sleep(50); /* some delay, so that thread2 can try to acquire a second exclusive lock */
2309 if (InterlockedIncrement(&srwlock_seq) != 16)
2310 InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
2311
2312 /* seq 18 */
2313 pAcquireSRWLockShared(&srwlock_base);
2314 if (srwlock_seq != 18)
2315 InterlockedIncrement(&srwlock_base_errors.excl_not_preferred);
2316 pReleaseSRWLockShared(&srwlock_base);
2317 if (InterlockedIncrement(&srwlock_seq) != 19)
2318 InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
2319
2320 /* skip over remaining tests if TryAcquireSRWLock* is not available */
2321 if (!pTryAcquireSRWLockExclusive)
2322 {
2323 /* function is only in Windows 7 and newer */
2324 win_skip("no srw trylock support.\n");
2325 srwlock_seq = 31; /* end */
2326 return 0;
2327 }
2328
2329 return 0;
2330 }
2331
2332 static void test_srwlock_base(void)
2333 {
2334 HANDLE h1, h2, h3;
2335 DWORD dummy;
2336
2337 if (!pInitializeSRWLock)
2338 {
2339 /* function is not yet in XP, only in newer Windows */
2340 win_skip("no srw lock support.\n");
2341 return;
2342 }
2343
2344 pInitializeSRWLock(&srwlock_base);
2345 memset(&srwlock_base_errors, 0, sizeof(srwlock_base_errors));
2346
2347 h1 = CreateThread(NULL, 0, srwlock_base_thread1, NULL, 0, &dummy);
2348 h2 = CreateThread(NULL, 0, srwlock_base_thread2, NULL, 0, &dummy);
2349 h3 = CreateThread(NULL, 0, srwlock_base_thread3, NULL, 0, &dummy);
2350
2351 srwlock_seq = 1; /* go */
2352 while (srwlock_seq < 31)
2353 Sleep(5);
2354
2355 WaitForSingleObject(h1, 100);
2356 WaitForSingleObject(h2, 100);
2357 WaitForSingleObject(h3, 100);
2358
2359 ok(!srwlock_base_errors.wrong_execution_order,
2360 "thread commands were executed in the wrong order (occurred %d times).\n",
2361 srwlock_base_errors.wrong_execution_order);
2362
2363 ok(!srwlock_base_errors.samethread_excl_excl,
2364 "AcquireSRWLockExclusive didn't block when called multiple times from the same thread (occurred %d times).\n",
2365 srwlock_base_errors.samethread_excl_excl);
2366
2367 ok(!srwlock_base_errors.samethread_excl_shared,
2368 "AcquireSRWLockShared didn't block when the same thread holds an exclusive lock (occurred %d times).\n",
2369 srwlock_base_errors.samethread_excl_shared);
2370
2371 ok(!srwlock_base_errors.samethread_shared_excl,
2372 "AcquireSRWLockExclusive didn't block when the same thread holds a shared lock (occurred %d times).\n",
2373 srwlock_base_errors.samethread_shared_excl);
2374
2375 ok(!srwlock_base_errors.multithread_excl_excl,
2376 "AcquireSRWLockExclusive didn't block when a second thread holds the exclusive lock (occurred %d times).\n",
2377 srwlock_base_errors.multithread_excl_excl);
2378
2379 ok(!srwlock_base_errors.excl_not_preferred,
2380 "thread waiting for exclusive access to the SHMLock was not preferred (occurred %d times).\n",
2381 srwlock_base_errors.excl_not_preferred);
2382
2383 ok(!srwlock_base_errors.trylock_excl,
2384 "TryAcquireSRWLockExclusive didn't behave as expected (occurred %d times).\n",
2385 srwlock_base_errors.trylock_excl);
2386
2387 ok(!srwlock_base_errors.trylock_shared,
2388 "TryAcquireSRWLockShared didn't behave as expected (occurred %d times).\n",
2389 srwlock_base_errors.trylock_shared);
2390
2391 }
2392
2393 static SRWLOCK srwlock_example;
2394 static LONG srwlock_protected_value = 0;
2395 static LONG srwlock_example_errors = 0, srwlock_inside = 0, srwlock_cnt = 0;
2396 static BOOL srwlock_stop = FALSE;
2397
2398 static DWORD WINAPI srwlock_example_thread(LPVOID x) {
2399 DWORD *cnt = x;
2400 LONG old;
2401
2402 while (!srwlock_stop)
2403 {
2404
2405 /* periodically request exclusive access */
2406 if (InterlockedIncrement(&srwlock_cnt) % 13 == 0)
2407 {
2408 pAcquireSRWLockExclusive(&srwlock_example);
2409 if (InterlockedIncrement(&srwlock_inside) != 1)
2410 InterlockedIncrement(&srwlock_example_errors);
2411
2412 InterlockedIncrement(&srwlock_protected_value);
2413 Sleep(1);
2414
2415 if (InterlockedDecrement(&srwlock_inside) != 0)
2416 InterlockedIncrement(&srwlock_example_errors);
2417 pReleaseSRWLockExclusive(&srwlock_example);
2418 }
2419
2420 /* request shared access */
2421 pAcquireSRWLockShared(&srwlock_example);
2422 InterlockedIncrement(&srwlock_inside);
2423 old = srwlock_protected_value;
2424
2425 (*cnt)++;
2426 Sleep(1);
2427
2428 if (old != srwlock_protected_value)
2429 InterlockedIncrement(&srwlock_example_errors);
2430 InterlockedDecrement(&srwlock_inside);
2431 pReleaseSRWLockShared(&srwlock_example);
2432 }
2433
2434 return 0;
2435 }
2436
2437 static void test_srwlock_example(void)
2438 {
2439 HANDLE h1, h2, h3;
2440 DWORD dummy;
2441 DWORD cnt1, cnt2, cnt3;
2442
2443 if (!pInitializeSRWLock) {
2444 /* function is not yet in XP, only in newer Windows */
2445 win_skip("no srw lock support.\n");
2446 return;
2447 }
2448
2449 pInitializeSRWLock(&srwlock_example);
2450
2451 cnt1 = cnt2 = cnt3 = 0;
2452
2453 h1 = CreateThread(NULL, 0, srwlock_example_thread, &cnt1, 0, &dummy);
2454 h2 = CreateThread(NULL, 0, srwlock_example_thread, &cnt2, 0, &dummy);
2455 h3 = CreateThread(NULL, 0, srwlock_example_thread, &cnt3, 0, &dummy);
2456
2457 /* limit run to 1 second. */
2458 Sleep(1000);
2459
2460 /* tear down start */
2461 srwlock_stop = TRUE;
2462
2463 WaitForSingleObject(h1, 1000);
2464 WaitForSingleObject(h2, 1000);
2465 WaitForSingleObject(h3, 1000);
2466
2467 ok(!srwlock_inside, "threads didn't terminate properly, srwlock_inside is %d.\n", srwlock_inside);
2468 ok(!srwlock_example_errors, "errors occurred while running SRWLock example test (number of errors: %d)\n",
2469 srwlock_example_errors);
2470
2471 trace("number of shared accesses per thread are c1 %d, c2 %d, c3 %d\n", cnt1, cnt2, cnt3);
2472 trace("number of total exclusive accesses is %d\n", srwlock_protected_value);
2473 }
2474
2475 static DWORD WINAPI alertable_wait_thread(void *param)
2476 {
2477 HANDLE *semaphores = param;
2478 LARGE_INTEGER timeout;
2479 NTSTATUS status;
2480 DWORD result;
2481
2482 ReleaseSemaphore(semaphores[0], 1, NULL);
2483 result = WaitForMultipleObjectsEx(1, &semaphores[1], TRUE, 1000, TRUE);
2484 ok(result == WAIT_IO_COMPLETION, "expected WAIT_IO_COMPLETION, got %u\n", result);
2485 result = WaitForMultipleObjectsEx(1, &semaphores[1], TRUE, 200, TRUE);
2486 ok(result == WAIT_OBJECT_0, "expected WAIT_OBJECT_0, got %u\n", result);
2487
2488 ReleaseSemaphore(semaphores[0], 1, NULL);
2489 timeout.QuadPart = -10000000;
2490 status = pNtWaitForMultipleObjects(1, &semaphores[1], FALSE, TRUE, &timeout);
2491 ok(status == STATUS_USER_APC, "expected STATUS_USER_APC, got %08x\n", status);
2492 timeout.QuadPart = -2000000;
2493 status = pNtWaitForMultipleObjects(1, &semaphores[1], FALSE, TRUE, &timeout);
2494 ok(status == STATUS_WAIT_0, "expected STATUS_WAIT_0, got %08x\n", status);
2495
2496 ReleaseSemaphore(semaphores[0], 1, NULL);
2497 timeout.QuadPart = -10000000;
2498 status = pNtWaitForMultipleObjects(1, &semaphores[1], FALSE, TRUE, &timeout);
2499 ok(status == STATUS_USER_APC, "expected STATUS_USER_APC, got %08x\n", status);
2500 result = WaitForSingleObject(semaphores[0], 0);
2501 ok(result == WAIT_TIMEOUT, "expected WAIT_TIMEOUT, got %u\n", result);
2502
2503 return 0;
2504 }
2505
2506 static void CALLBACK alertable_wait_apc(ULONG_PTR userdata)
2507 {
2508 HANDLE *semaphores = (void *)userdata;
2509 ReleaseSemaphore(semaphores[1], 1, NULL);
2510 }
2511
2512 static void CALLBACK alertable_wait_apc2(ULONG_PTR userdata)
2513 {
2514 HANDLE *semaphores = (void *)userdata;
2515 DWORD result;
2516
2517 result = WaitForSingleObject(semaphores[0], 1000);
2518 ok(result == WAIT_OBJECT_0, "expected WAIT_OBJECT_0, got %u\n", result);
2519 }
2520
2521 static void test_alertable_wait(void)
2522 {
2523 HANDLE thread, semaphores[2];
2524 DWORD result;
2525
2526 semaphores[0] = CreateSemaphoreW(NULL, 0, 2, NULL);
2527 ok(semaphores[0] != NULL, "CreateSemaphore failed with %u\n", GetLastError());
2528 semaphores[1] = CreateSemaphoreW(NULL, 0, 1, NULL);
2529 ok(semaphores[1] != NULL, "CreateSemaphore failed with %u\n", GetLastError());
2530 thread = CreateThread(NULL, 0, alertable_wait_thread, semaphores, 0, NULL);
2531 ok(thread != NULL, "CreateThread failed with %u\n", GetLastError());
2532
2533 result = WaitForSingleObject(semaphores[0], 1000);
2534 ok(result == WAIT_OBJECT_0, "expected WAIT_OBJECT_0, got %u\n", result);
2535 Sleep(100); /* ensure the thread is blocking in WaitForMultipleObjectsEx */
2536 result = QueueUserAPC(alertable_wait_apc, thread, (ULONG_PTR)semaphores);
2537 ok(result != 0, "QueueUserAPC failed with %u\n", GetLastError());
2538
2539 result = WaitForSingleObject(semaphores[0], 1000);
2540 ok(result == WAIT_OBJECT_0, "expected WAIT_OBJECT_0, got %u\n", result);
2541 Sleep(100); /* ensure the thread is blocking in NtWaitForMultipleObjects */
2542 result = QueueUserAPC(alertable_wait_apc, thread, (ULONG_PTR)semaphores);
2543 ok(result != 0, "QueueUserAPC failed with %u\n", GetLastError());
2544
2545 result = WaitForSingleObject(semaphores[0], 1000);
2546 ok(result == WAIT_OBJECT_0, "expected WAIT_OBJECT_0, got %u\n", result);
2547 Sleep(100); /* ensure the thread is blocking in NtWaitForMultipleObjects */
2548 result = QueueUserAPC(alertable_wait_apc2, thread, (ULONG_PTR)semaphores);
2549 ok(result != 0, "QueueUserAPC failed with %u\n", GetLastError());
2550 result = QueueUserAPC(alertable_wait_apc2, thread, (ULONG_PTR)semaphores);
2551 ok(result != 0, "QueueUserAPC failed with %u\n", GetLastError());
2552 ReleaseSemaphore(semaphores[0], 2, NULL);
2553
2554 result = WaitForSingleObject(thread, 1000);
2555 ok(result == WAIT_OBJECT_0, "expected WAIT_OBJECT_0, got %u\n", result);
2556 CloseHandle(thread);
2557 CloseHandle(semaphores[0]);
2558 CloseHandle(semaphores[1]);
2559 }
2560
2561 struct apc_deadlock_info
2562 {
2563 PROCESS_INFORMATION *pi;
2564 HANDLE event;
2565 BOOL running;
2566 };
2567
2568 static DWORD WINAPI apc_deadlock_thread(void *param)
2569 {
2570 struct apc_deadlock_info *info = param;
2571 PROCESS_INFORMATION *pi = info->pi;
2572 NTSTATUS status;
2573 SIZE_T size;
2574 void *base;
2575
2576 while (info->running)
2577 {
2578 base = NULL;
2579 size = 0x1000;
2580 status = pNtAllocateVirtualMemory(pi->hProcess, &base, 0, &size,
2581 MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
2582 ok(!status, "expected STATUS_SUCCESS, got %08x\n", status);
2583 ok(base != NULL, "expected base != NULL, got %p\n", base);
2584 SetEvent(info->event);
2585
2586 size = 0;
2587 status = pNtFreeVirtualMemory(pi->hProcess, &base, &size, MEM_RELEASE);
2588 ok(!status, "expected STATUS_SUCCESS, got %08x\n", status);
2589 SetEvent(info->event);
2590 }
2591
2592 return 0;
2593 }
2594
2595 static void test_apc_deadlock(void)
2596 {
2597 struct apc_deadlock_info info;
2598 PROCESS_INFORMATION pi;
2599 STARTUPINFOA si = { sizeof(si) };
2600 char cmdline[MAX_PATH];
2601 HANDLE event, thread;
2602 DWORD result;
2603 BOOL success;
2604 char **argv;
2605 int i;
2606
2607 winetest_get_mainargs(&argv);
2608 sprintf(cmdline, "\"%s\" sync apc_deadlock", argv[0]);
2609 success = CreateProcessA(argv[0], cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
2610 ok(success, "CreateProcess failed with %u\n", GetLastError());
2611
2612 event = CreateEventA(NULL, FALSE, FALSE, NULL);
2613 ok(event != NULL, "CreateEvent failed with %u\n", GetLastError());
2614
2615 info.pi = &pi;
2616 info.event = event;
2617 info.running = TRUE;
2618
2619 thread = CreateThread(NULL, 0, apc_deadlock_thread, &info, 0, NULL);
2620 ok(thread != NULL, "CreateThread failed with %u\n", GetLastError());
2621 result = WaitForSingleObject(event, 1000);
2622 ok(result == WAIT_OBJECT_0, "expected WAIT_OBJECT_0, got %u\n", result);
2623
2624 for (i = 0; i < 1000; i++)
2625 {
2626 result = SuspendThread(pi.hThread);
2627 ok(result == 0, "expected 0, got %u\n", result);
2628
2629 WaitForSingleObject(event, 0); /* reset event */
2630 result = WaitForSingleObject(event, 1000);
2631 ok(result == WAIT_OBJECT_0, "expected WAIT_OBJECT_0, got %u\n", result);
2632
2633 result = ResumeThread(pi.hThread);
2634 ok(result == 1, "expected 1, got %u\n", result);
2635 Sleep(1);
2636 }
2637
2638 info.running = FALSE;
2639 result = WaitForSingleObject(thread, 1000);
2640 ok(result == WAIT_OBJECT_0, "expected WAIT_OBJECT_0, got %u\n", result);
2641 CloseHandle(thread);
2642 CloseHandle(event);
2643
2644 TerminateProcess(pi.hProcess, 0);
2645 CloseHandle(pi.hThread);
2646 CloseHandle(pi.hProcess);
2647 }
2648
2649 START_TEST(sync)
2650 {
2651 char **argv;
2652 int argc;
2653 HMODULE hdll = GetModuleHandleA("kernel32.dll");
2654 HMODULE hntdll = GetModuleHandleA("ntdll.dll");
2655
2656 pChangeTimerQueueTimer = (void*)GetProcAddress(hdll, "ChangeTimerQueueTimer");
2657 pCreateTimerQueue = (void*)GetProcAddress(hdll, "CreateTimerQueue");
2658 pCreateTimerQueueTimer = (void*)GetProcAddress(hdll, "CreateTimerQueueTimer");
2659 pCreateWaitableTimerA = (void*)GetProcAddress(hdll, "CreateWaitableTimerA");
2660 pDeleteTimerQueueEx = (void*)GetProcAddress(hdll, "DeleteTimerQueueEx");
2661 pDeleteTimerQueueTimer = (void*)GetProcAddress(hdll, "DeleteTimerQueueTimer");
2662 pOpenWaitableTimerA = (void*)GetProcAddress(hdll, "OpenWaitableTimerA");
2663 pCreateMemoryResourceNotification = (void *)GetProcAddress(hdll, "CreateMemoryResourceNotification");
2664 pQueryMemoryResourceNotification = (void *)GetProcAddress(hdll, "QueryMemoryResourceNotification");
2665 pInitOnceInitialize = (void *)GetProcAddress(hdll, "InitOnceInitialize");
2666 pInitOnceExecuteOnce = (void *)GetProcAddress(hdll, "InitOnceExecuteOnce");
2667 pInitOnceBeginInitialize = (void *)GetProcAddress(hdll, "InitOnceBeginInitialize");
2668 pInitOnceComplete = (void *)GetProcAddress(hdll, "InitOnceComplete");
2669 pInitializeConditionVariable = (void *)GetProcAddress(hdll, "InitializeConditionVariable");
2670 pSleepConditionVariableCS = (void *)GetProcAddress(hdll, "SleepConditionVariableCS");
2671 pSleepConditionVariableSRW = (void *)GetProcAddress(hdll, "SleepConditionVariableSRW");
2672 pWakeAllConditionVariable = (void *)GetProcAddress(hdll, "WakeAllConditionVariable");
2673 pWakeConditionVariable = (void *)GetProcAddress(hdll, "WakeConditionVariable");
2674 pInitializeSRWLock = (void *)GetProcAddress(hdll, "InitializeSRWLock");
2675 pAcquireSRWLockExclusive = (void *)GetProcAddress(hdll, "AcquireSRWLockExclusive");
2676 pAcquireSRWLockShared = (void *)GetProcAddress(hdll, "AcquireSRWLockShared");
2677 pReleaseSRWLockExclusive = (void *)GetProcAddress(hdll, "ReleaseSRWLockExclusive");
2678 pReleaseSRWLockShared = (void *)GetProcAddress(hdll, "ReleaseSRWLockShared");
2679 pTryAcquireSRWLockExclusive = (void *)GetProcAddress(hdll, "TryAcquireSRWLockExclusive");
2680 pTryAcquireSRWLockShared = (void *)GetProcAddress(hdll, "TryAcquireSRWLockShared");
2681 pNtAllocateVirtualMemory = (void *)GetProcAddress(hntdll, "NtAllocateVirtualMemory");
2682 pNtFreeVirtualMemory = (void *)GetProcAddress(hntdll, "NtFreeVirtualMemory");
2683 pNtWaitForSingleObject = (void *)GetProcAddress(hntdll, "NtWaitForSingleObject");
2684 pNtWaitForMultipleObjects = (void *)GetProcAddress(hntdll, "NtWaitForMultipleObjects");
2685 pRtlInterlockedPushListSList = (void *)GetProcAddress(hntdll, "RtlInterlockedPushListSList");
2686 pRtlInterlockedPushListSListEx = (void *)GetProcAddress(hntdll, "RtlInterlockedPushListSListEx");
2687
2688 argc = winetest_get_mainargs( &argv );
2689 if (argc >= 3)
2690 {
2691 if (!strcmp(argv[2], "apc_deadlock"))
2692 {
2693 for (;;) SleepEx(INFINITE, TRUE);
2694 }
2695 return;
2696 }
2697
2698 init_fastcall_thunk();
2699 test_signalandwait();
2700 test_mutex();
2701 test_slist();
2702 test_event();
2703 test_semaphore();
2704 test_waitable_timer();
2705 test_iocp_callback();
2706 test_timer_queue();
2707 test_WaitForSingleObject();
2708 test_WaitForMultipleObjects();
2709 test_initonce();
2710 test_condvars_base();
2711 test_condvars_consumer_producer();
2712 test_srwlock_base();
2713 test_srwlock_example();
2714 test_alertable_wait();
2715 test_apc_deadlock();
2716 }