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