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