Remove unnecessary executable bits
[reactos.git] / modules / rostests / winetests / kernel32 / sync.c
1 /*
2 * Synchronization tests
3 *
4 * Copyright 2005 Mike McCormack for CodeWeavers
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 */
20
21 #ifndef __REACTOS__
22 #define _WIN32_WINNT 0x500
23 #endif
24 #include <stdarg.h>
25 #include <stdlib.h>
26 #include <stdio.h>
27 #include <windef.h>
28 #include <winbase.h>
29 #include <winternl.h>
30
31 #include "wine/test.h"
32
33 #ifdef __REACTOS__
34 #define QueryDepthSList(x) RtlQueryDepthSList(x)
35 #define InterlockedPushEntrySList(x,y) RtlInterlockedPushEntrySList(x,y)
36 #define InterlockedPopEntrySList(x) RtlInterlockedPopEntrySList(x)
37 #define InterlockedFlushSList(x) RtlInterlockedFlushSList(x)
38 #endif
39
40 #undef __fastcall
41 #define __fastcall __stdcall
42
43 static HANDLE (WINAPI *pCreateMemoryResourceNotification)(MEMORY_RESOURCE_NOTIFICATION_TYPE);
44 static BOOL (WINAPI *pQueryMemoryResourceNotification)(HANDLE, PBOOL);
45 static VOID (WINAPI *pInitOnceInitialize)(PINIT_ONCE);
46 static BOOL (WINAPI *pInitOnceExecuteOnce)(PINIT_ONCE,PINIT_ONCE_FN,PVOID,LPVOID*);
47 static BOOL (WINAPI *pInitOnceBeginInitialize)(PINIT_ONCE,DWORD,BOOL*,LPVOID*);
48 static BOOL (WINAPI *pInitOnceComplete)(PINIT_ONCE,DWORD,LPVOID);
49
50 static VOID (WINAPI *pInitializeConditionVariable)(PCONDITION_VARIABLE);
51 static BOOL (WINAPI *pSleepConditionVariableCS)(PCONDITION_VARIABLE,PCRITICAL_SECTION,DWORD);
52 static BOOL (WINAPI *pSleepConditionVariableSRW)(PCONDITION_VARIABLE,PSRWLOCK,DWORD,ULONG);
53 static VOID (WINAPI *pWakeAllConditionVariable)(PCONDITION_VARIABLE);
54 static VOID (WINAPI *pWakeConditionVariable)(PCONDITION_VARIABLE);
55
56 static VOID (WINAPI *pInitializeSRWLock)(PSRWLOCK);
57 static VOID (WINAPI *pAcquireSRWLockExclusive)(PSRWLOCK);
58 static VOID (WINAPI *pAcquireSRWLockShared)(PSRWLOCK);
59 static VOID (WINAPI *pReleaseSRWLockExclusive)(PSRWLOCK);
60 static VOID (WINAPI *pReleaseSRWLockShared)(PSRWLOCK);
61 static BOOLEAN (WINAPI *pTryAcquireSRWLockExclusive)(PSRWLOCK);
62 static BOOLEAN (WINAPI *pTryAcquireSRWLockShared)(PSRWLOCK);
63
64 static NTSTATUS (WINAPI *pNtAllocateVirtualMemory)(HANDLE, PVOID *, ULONG, SIZE_T *, ULONG, ULONG);
65 static NTSTATUS (WINAPI *pNtFreeVirtualMemory)(HANDLE, PVOID *, SIZE_T *, ULONG);
66 static NTSTATUS (WINAPI *pNtWaitForSingleObject)(HANDLE, BOOLEAN, const LARGE_INTEGER *);
67 static NTSTATUS (WINAPI *pNtWaitForMultipleObjects)(ULONG,const HANDLE*,BOOLEAN,BOOLEAN,const LARGE_INTEGER*);
68 static PSLIST_ENTRY (__fastcall *pRtlInterlockedPushListSList)(PSLIST_HEADER list, PSLIST_ENTRY first,
69 PSLIST_ENTRY last, ULONG count);
70 static PSLIST_ENTRY (WINAPI *pRtlInterlockedPushListSListEx)(PSLIST_HEADER list, PSLIST_ENTRY first,
71 PSLIST_ENTRY last, ULONG count);
72
73 #ifdef __i386__
74
75 #include "pshpack1.h"
76 struct fastcall_thunk
77 {
78 BYTE pop_edx; /* popl %edx (ret addr) */
79 BYTE pop_eax; /* popl %eax (func) */
80 BYTE pop_ecx; /* popl %ecx (param 1) */
81 BYTE xchg[3]; /* xchgl (%esp),%edx (param 2) */
82 WORD jmp_eax; /* jmp *%eax */
83 };
84 #include "poppack.h"
85
86 static void * (WINAPI *call_fastcall_func4)(void *func, const void *a, const void *b, const void *c, const void *d);
87
88 static void init_fastcall_thunk(void)
89 {
90 struct fastcall_thunk *thunk = VirtualAlloc(NULL, sizeof(*thunk), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
91 thunk->pop_edx = 0x5a; /* popl %edx */
92 thunk->pop_eax = 0x58; /* popl %eax */
93 thunk->pop_ecx = 0x59; /* popl %ecx */
94 thunk->xchg[0] = 0x87; /* xchgl (%esp),%edx */
95 thunk->xchg[1] = 0x14;
96 thunk->xchg[2] = 0x24;
97 thunk->jmp_eax = 0xe0ff; /* jmp *%eax */
98 call_fastcall_func4 = (void *)thunk;
99 }
100
101 #define call_func4(func, a, b, c, d) call_fastcall_func4(func, (const void *)(a), \
102 (const void *)(b), (const void *)(c), (const void *)(d))
103
104 #else /* __i386__ */
105
106 #define init_fastcall_thunk() do { } while(0)
107 #define call_func4(func, a, b, c, d) func(a, b, c, d)
108
109 #endif /* __i386__ */
110
111 static void test_signalandwait(void)
112 {
113 DWORD r;
114 HANDLE event[2], semaphore[2], file;
115 int i;
116
117 /* invalid parameters */
118 r = SignalObjectAndWait(NULL, NULL, 0, 0);
119 ok( r == WAIT_FAILED, "should fail\n");
120
121 event[0] = CreateEventW(NULL, 0, 0, NULL);
122 event[1] = CreateEventW(NULL, 1, 1, NULL);
123
124 ok( event[0] && event[1], "failed to create event flags\n");
125
126 r = SignalObjectAndWait(event[0], NULL, 0, FALSE);
127 ok( r == WAIT_FAILED, "should fail\n");
128
129 r = SignalObjectAndWait(NULL, event[0], 0, FALSE);
130 ok( r == WAIT_FAILED, "should fail\n");
131
132
133 /* valid parameters */
134 r = SignalObjectAndWait(event[0], event[1], 0, FALSE);
135 ok( r == WAIT_OBJECT_0, "should succeed\n");
136
137 /* event[0] is now signalled - we repeat this test multiple times
138 * to ensure that the wineserver handles this situation properly. */
139 for (i = 0; i < 10000; i++)
140 {
141 r = SignalObjectAndWait(event[0], event[0], 0, FALSE);
142 ok(r == WAIT_OBJECT_0, "should succeed\n");
143 }
144
145 /* event[0] is not signalled */
146 r = WaitForSingleObject(event[0], 0);
147 ok( r == WAIT_TIMEOUT, "event was signalled\n");
148
149 r = SignalObjectAndWait(event[0], event[0], 0, FALSE);
150 ok( r == WAIT_OBJECT_0, "should succeed\n");
151
152 /* clear event[1] and check for a timeout */
153 ok(ResetEvent(event[1]), "failed to clear event[1]\n");
154 r = SignalObjectAndWait(event[0], event[1], 0, FALSE);
155 ok( r == WAIT_TIMEOUT, "should timeout\n");
156
157 CloseHandle(event[0]);
158 CloseHandle(event[1]);
159
160 /* semaphores */
161 semaphore[0] = CreateSemaphoreW( NULL, 0, 1, NULL );
162 semaphore[1] = CreateSemaphoreW( NULL, 1, 1, NULL );
163 ok( semaphore[0] && semaphore[1], "failed to create semaphore\n");
164
165 r = SignalObjectAndWait(semaphore[0], semaphore[1], 0, FALSE);
166 ok( r == WAIT_OBJECT_0, "should succeed\n");
167
168 r = SignalObjectAndWait(semaphore[0], semaphore[1], 0, FALSE);
169 ok( r == WAIT_FAILED, "should fail\n");
170
171 r = ReleaseSemaphore(semaphore[0],1,NULL);
172 ok( r == FALSE, "should fail\n");
173
174 r = ReleaseSemaphore(semaphore[1],1,NULL);
175 ok( r == TRUE, "should succeed\n");
176
177 CloseHandle(semaphore[0]);
178 CloseHandle(semaphore[1]);
179
180 /* try a registry key */
181 file = CreateFileA("x", GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
182 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE, NULL);
183 r = SignalObjectAndWait(file, file, 0, FALSE);
184 ok( r == WAIT_FAILED, "should fail\n");
185 ok( ERROR_INVALID_HANDLE == GetLastError(), "should return invalid handle error\n");
186 CloseHandle(file);
187 }
188
189 static void test_mutex(void)
190 {
191 DWORD wait_ret;
192 BOOL ret;
193 HANDLE hCreated;
194 HANDLE hOpened;
195 int i;
196 DWORD failed = 0;
197
198 SetLastError(0xdeadbeef);
199 hOpened = OpenMutexA(0, FALSE, "WineTestMutex");
200 ok(hOpened == NULL, "OpenMutex succeeded\n");
201 ok(GetLastError() == ERROR_FILE_NOT_FOUND, "wrong error %u\n", GetLastError());
202
203 SetLastError(0xdeadbeef);
204 hCreated = CreateMutexA(NULL, FALSE, "WineTestMutex");
205 ok(hCreated != NULL, "CreateMutex failed with error %d\n", GetLastError());
206
207 SetLastError(0xdeadbeef);
208 hOpened = OpenMutexA(0, FALSE, "WineTestMutex");
209 todo_wine
210 ok(hOpened == NULL, "OpenMutex succeeded\n");
211 todo_wine
212 ok(GetLastError() == ERROR_ACCESS_DENIED, "wrong error %u\n", GetLastError());
213
214 SetLastError(0xdeadbeef);
215 hOpened = OpenMutexA(GENERIC_EXECUTE, FALSE, "WineTestMutex");
216 ok(hOpened != NULL, "OpenMutex failed with error %d\n", GetLastError());
217 wait_ret = WaitForSingleObject(hOpened, INFINITE);
218 ok(wait_ret == WAIT_OBJECT_0, "WaitForSingleObject failed with error %d\n", GetLastError());
219 CloseHandle(hOpened);
220
221 for(i=0; i < 31; i++)
222 {
223 wait_ret = WaitForSingleObject(hCreated, INFINITE);
224 ok(wait_ret == WAIT_OBJECT_0, "WaitForSingleObject failed with error 0x%08x\n", wait_ret);
225 }
226
227 SetLastError(0xdeadbeef);
228 hOpened = OpenMutexA(GENERIC_READ | GENERIC_WRITE, FALSE, "WineTestMutex");
229 ok(hOpened != NULL, "OpenMutex failed with error %d\n", GetLastError());
230 wait_ret = WaitForSingleObject(hOpened, INFINITE);
231 ok(wait_ret == WAIT_FAILED, "WaitForSingleObject succeeded\n");
232 CloseHandle(hOpened);
233
234 for (i = 0; i < 32; i++)
235 {
236 SetLastError(0xdeadbeef);
237 hOpened = OpenMutexA(0x1 << i, FALSE, "WineTestMutex");
238 if(hOpened != NULL)
239 {
240 SetLastError(0xdeadbeef);
241 ret = ReleaseMutex(hOpened);
242 ok(ret, "ReleaseMutex failed with error %d, access %x\n", GetLastError(), 1 << i);
243 CloseHandle(hOpened);
244 }
245 else
246 {
247 if ((1 << i) == ACCESS_SYSTEM_SECURITY)
248 todo_wine ok(GetLastError() == ERROR_PRIVILEGE_NOT_HELD, "wrong error %u, access %x\n", GetLastError(), 1 << i);
249 else
250 todo_wine ok(GetLastError() == ERROR_ACCESS_DENIED, "wrong error %u, , access %x\n", GetLastError(), 1 << i);
251 ReleaseMutex(hCreated);
252 failed |=0x1 << i;
253 }
254 }
255
256 todo_wine
257 ok( failed == 0x0de0fffe, "open succeeded when it shouldn't: %x\n", failed);
258
259 SetLastError(0xdeadbeef);
260 ret = ReleaseMutex(hCreated);
261 ok(!ret && (GetLastError() == ERROR_NOT_OWNER),
262 "ReleaseMutex should have failed with ERROR_NOT_OWNER instead of %d\n", GetLastError());
263
264 /* test case sensitivity */
265
266 SetLastError(0xdeadbeef);
267 hOpened = OpenMutexA(READ_CONTROL, FALSE, "WINETESTMUTEX");
268 ok(!hOpened, "OpenMutex succeeded\n");
269 ok(GetLastError() == ERROR_FILE_NOT_FOUND, "wrong error %u\n", GetLastError());
270
271 SetLastError(0xdeadbeef);
272 hOpened = OpenMutexA(READ_CONTROL, FALSE, "winetestmutex");
273 ok(!hOpened, "OpenMutex succeeded\n");
274 ok(GetLastError() == ERROR_FILE_NOT_FOUND, "wrong error %u\n", GetLastError());
275
276 SetLastError(0xdeadbeef);
277 hOpened = OpenMutexA(READ_CONTROL, FALSE, NULL);
278 ok(!hOpened, "OpenMutex succeeded\n");
279 ok(GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError());
280
281 SetLastError(0xdeadbeef);
282 hOpened = OpenMutexW(READ_CONTROL, FALSE, NULL);
283 ok(!hOpened, "OpenMutex succeeded\n");
284 ok(GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError());
285
286 SetLastError(0xdeadbeef);
287 hOpened = CreateMutexA(NULL, FALSE, "WineTestMutex");
288 ok(hOpened != NULL, "CreateMutex failed with error %d\n", GetLastError());
289 ok(GetLastError() == ERROR_ALREADY_EXISTS, "wrong error %u\n", GetLastError());
290 CloseHandle(hOpened);
291
292 SetLastError(0xdeadbeef);
293 hOpened = CreateMutexA(NULL, FALSE, "WINETESTMUTEX");
294 ok(hOpened != NULL, "CreateMutex failed with error %d\n", GetLastError());
295 ok(GetLastError() == 0, "wrong error %u\n", GetLastError());
296 CloseHandle(hOpened);
297
298 CloseHandle(hCreated);
299 }
300
301 static void test_slist(void)
302 {
303 struct item
304 {
305 SLIST_ENTRY entry;
306 int value;
307 } item1, item2, item3, *item;
308 SLIST_HEADER slist_header;
309 SLIST_ENTRY *entry;
310 USHORT size;
311 int i;
312
313 item1.value = 1;
314 item2.value = 2;
315 item3.value = 3;
316
317 memset(&slist_header, 0xff, sizeof(slist_header));
318 InitializeSListHead(&slist_header);
319 size = QueryDepthSList(&slist_header);
320 ok(size == 0, "Expected size == 0, got %u\n", size);
321
322 /* test PushEntry, PopEntry and Flush */
323 entry = InterlockedPushEntrySList(&slist_header, &item1.entry);
324 ok(entry == NULL, "Expected entry == NULL, got %p\n", entry);
325 size = QueryDepthSList(&slist_header);
326 ok(size == 1, "Expected size == 1, got %u\n", size);
327
328 entry = InterlockedPushEntrySList(&slist_header, &item2.entry);
329 ok(entry != NULL, "Expected entry != NULL, got %p\n", entry);
330 item = CONTAINING_RECORD(entry, struct item, entry);
331 ok(item->value == 1, "Expected item->value == 1, got %u\n", item->value);
332 size = QueryDepthSList(&slist_header);
333 ok(size == 2, "Expected size == 2, got %u\n", size);
334
335 entry = InterlockedPushEntrySList(&slist_header, &item3.entry);
336 ok(entry != NULL, "Expected entry != NULL, got %p\n", entry);
337 item = CONTAINING_RECORD(entry, struct item, entry);
338 ok(item->value == 2, "Expected item->value == 2, got %u\n", item->value);
339 size = QueryDepthSList(&slist_header);
340 ok(size == 3, "Expected size == 3, got %u\n", size);
341
342 entry = InterlockedPopEntrySList(&slist_header);
343 ok(entry != NULL, "Expected entry != NULL, got %p\n", entry);
344 item = CONTAINING_RECORD(entry, struct item, entry);
345 ok(item->value == 3, "Expected item->value == 3, got %u\n", item->value);
346 size = QueryDepthSList(&slist_header);
347 ok(size == 2, "Expected size == 2, got %u\n", size);
348
349 entry = InterlockedFlushSList(&slist_header);
350 ok(entry != NULL, "Expected entry != NULL, got %p\n", entry);
351 item = CONTAINING_RECORD(entry, struct item, entry);
352 ok(item->value == 2, "Expected item->value == 2, got %u\n", item->value);
353 item = CONTAINING_RECORD(item->entry.Next, struct item, entry);
354 ok(item->value == 1, "Expected item->value == 1, got %u\n", item->value);
355 size = QueryDepthSList(&slist_header);
356 ok(size == 0, "Expected size == 0, got %u\n", size);
357 entry = InterlockedPopEntrySList(&slist_header);
358 ok(entry == NULL, "Expected entry == NULL, got %p\n", entry);
359
360 /* test RtlInterlockedPushListSList */
361 entry = InterlockedPushEntrySList(&slist_header, &item3.entry);
362 ok(entry == NULL, "Expected entry == NULL, got %p\n", entry);
363 entry = call_func4(pRtlInterlockedPushListSList, &slist_header, &item2.entry, &item1.entry, 42);
364 ok(entry != NULL, "Expected entry != NULL, got %p\n", entry);
365 item = CONTAINING_RECORD(entry, struct item, entry);
366 ok(item->value == 3, "Expected item->value == 3, got %u\n", item->value);
367 size = QueryDepthSList(&slist_header);
368 ok(size == 43, "Expected size == 43, got %u\n", size);
369
370 entry = InterlockedPopEntrySList(&slist_header);
371 ok(entry != NULL, "Expected entry != NULL, got %p\n", entry);
372 item = CONTAINING_RECORD(entry, struct item, entry);
373 ok(item->value == 2, "Expected item->value == 2, got %u\n", item->value);
374 size = QueryDepthSList(&slist_header);
375 ok(size == 42, "Expected size == 42, got %u\n", size);
376
377 entry = InterlockedPopEntrySList(&slist_header);
378 ok(entry != NULL, "Expected entry != NULL, got %p\n", entry);
379 item = CONTAINING_RECORD(entry, struct item, entry);
380 ok(item->value == 1, "Expected item->value == 1, got %u\n", item->value);
381 size = QueryDepthSList(&slist_header);
382 ok(size == 41, "Expected size == 41, got %u\n", size);
383
384 entry = InterlockedPopEntrySList(&slist_header);
385 ok(entry != NULL, "Expected entry != NULL, got %p\n", entry);
386 item = CONTAINING_RECORD(entry, struct item, entry);
387 ok(item->value == 3, "Expected item->value == 3, got %u\n", item->value);
388 size = QueryDepthSList(&slist_header);
389 ok(size == 40, "Expected size == 40, got %u\n", size);
390
391 entry = InterlockedPopEntrySList(&slist_header);
392 ok(entry == NULL, "Expected entry == NULL, got %p\n", entry);
393 size = QueryDepthSList(&slist_header);
394 ok(size == 40, "Expected size == 40, got %u\n", size);
395
396 entry = InterlockedFlushSList(&slist_header);
397 ok(entry == NULL, "Expected entry == NULL, got %p\n", entry);
398 size = QueryDepthSList(&slist_header);
399 ok(size == 40 || broken(size == 0) /* >= Win 8 */, "Expected size == 40, got %u\n", size);
400
401 entry = InterlockedPushEntrySList(&slist_header, &item1.entry);
402 ok(entry == NULL, "Expected entry == NULL, got %p\n", entry);
403 entry = InterlockedFlushSList(&slist_header);
404 ok(entry != NULL, "Expected entry != NULL, got %p\n", entry);
405 item = CONTAINING_RECORD(entry, struct item, entry);
406 ok(item->value == 1, "Expected item->value == 1, got %u\n", item->value);
407 size = QueryDepthSList(&slist_header);
408 ok(size == 0, "Expected size == 0, got %u\n", size);
409
410 /* test RtlInterlockedPushListSListEx */
411 if (pRtlInterlockedPushListSListEx)
412 {
413 entry = InterlockedPushEntrySList(&slist_header, &item3.entry);
414 ok(entry == NULL, "Expected entry == NULL, got %p\n", entry);
415 entry = pRtlInterlockedPushListSListEx(&slist_header, &item2.entry, &item1.entry, 42);
416 ok(entry != NULL, "Expected entry != NULL, got %p\n", entry);
417 item = CONTAINING_RECORD(entry, struct item, entry);
418 ok(item->value == 3, "Expected item->value == 3, got %u\n", item->value);
419 size = QueryDepthSList(&slist_header);
420 ok(size == 43, "Expected size == 43, got %u\n", size);
421
422 entry = InterlockedFlushSList(&slist_header);
423 ok(entry != NULL, "Expected entry != NULL, got %p\n", entry);
424 item = CONTAINING_RECORD(entry, struct item, entry);
425 ok(item->value == 2, "Expected item->value == 2, got %u\n", item->value);
426 item = CONTAINING_RECORD(item->entry.Next, struct item, entry);
427 ok(item->value == 1, "Expected item->value == 1, got %u\n", item->value);
428 item = CONTAINING_RECORD(item->entry.Next, struct item, entry);
429 ok(item->value == 3, "Expected item->value == 3, got %u\n", item->value);
430 size = QueryDepthSList(&slist_header);
431 ok(size == 0, "Expected size == 0, got %u\n", size);
432 }
433 else
434 win_skip("RtlInterlockedPushListSListEx not available, skipping tests\n");
435
436 /* test with a lot of items */
437 for (i = 0; i < 65536; i++)
438 {
439 item = HeapAlloc(GetProcessHeap(), 0, sizeof(*item));
440 item->value = i + 1;
441 entry = InterlockedPushEntrySList(&slist_header, &item->entry);
442 if (i)
443 {
444 ok(entry != NULL, "Expected entry != NULL, got %p\n", entry);
445 item = CONTAINING_RECORD(entry, struct item, entry);
446 ok(item->value == i, "Expected item->value == %u, got %u\n", i, item->value);
447 }
448 else
449 {
450 ok(entry == NULL, "Expected entry == NULL, got %p\n", entry);
451 }
452 size = QueryDepthSList(&slist_header);
453 ok(size == ((i + 1) & 0xffff), "Expected size == %u, got %u\n", (i + 1) & 0xffff, size);
454 }
455
456 entry = InterlockedFlushSList(&slist_header);
457 for (i = 65536; i > 0; i--)
458 {
459 ok(entry != NULL, "Expected entry != NULL, got %p\n", entry);
460 item = CONTAINING_RECORD(entry, struct item, entry);
461 ok(item->value == i, "Expected item->value == %u, got %u\n", i, item->value);
462 entry = item->entry.Next;
463 HeapFree(GetProcessHeap(), 0, item);
464 }
465 ok(entry == NULL, "Expected entry == NULL, got %p\n", entry);
466 size = QueryDepthSList(&slist_header);
467 ok(size == 0, "Expected size == 0, got %u\n", size);
468 entry = InterlockedPopEntrySList(&slist_header);
469 ok(entry == NULL, "Expected entry == NULL, got %p\n", entry);
470 }
471
472 static void test_event(void)
473 {
474 HANDLE handle, handle2;
475 SECURITY_ATTRIBUTES sa;
476 SECURITY_DESCRIPTOR sd;
477 ACL acl;
478 DWORD ret;
479 BOOL val;
480
481 /* no sd */
482 handle = CreateEventA(NULL, FALSE, FALSE, __FILE__ ": Test Event");
483 ok(handle != NULL, "CreateEventW with blank sd failed with error %d\n", GetLastError());
484 CloseHandle(handle);
485
486 sa.nLength = sizeof(sa);
487 sa.lpSecurityDescriptor = &sd;
488 sa.bInheritHandle = FALSE;
489
490 InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);
491
492 /* blank sd */
493 handle = CreateEventA(&sa, FALSE, FALSE, __FILE__ ": Test Event");
494 ok(handle != NULL, "CreateEventW with blank sd failed with error %d\n", GetLastError());
495 CloseHandle(handle);
496
497 /* sd with NULL dacl */
498 SetSecurityDescriptorDacl(&sd, TRUE, NULL, FALSE);
499 handle = CreateEventA(&sa, FALSE, FALSE, __FILE__ ": Test Event");
500 ok(handle != NULL, "CreateEventW with blank sd failed with error %d\n", GetLastError());
501 CloseHandle(handle);
502
503 /* sd with empty dacl */
504 InitializeAcl(&acl, sizeof(acl), ACL_REVISION);
505 SetSecurityDescriptorDacl(&sd, TRUE, &acl, FALSE);
506 handle = CreateEventA(&sa, FALSE, FALSE, __FILE__ ": Test Event");
507 ok(handle != NULL, "CreateEventW with blank sd failed with error %d\n", GetLastError());
508 CloseHandle(handle);
509
510 /* test case sensitivity */
511
512 SetLastError(0xdeadbeef);
513 handle = CreateEventA(NULL, FALSE, FALSE, __FILE__ ": Test Event");
514 ok( handle != NULL, "CreateEvent failed with error %u\n", GetLastError());
515 ok( GetLastError() == 0, "wrong error %u\n", GetLastError());
516
517 SetLastError(0xdeadbeef);
518 handle2 = CreateEventA(NULL, FALSE, FALSE, __FILE__ ": Test Event");
519 ok( handle2 != NULL, "CreateEvent failed with error %d\n", GetLastError());
520 ok( GetLastError() == ERROR_ALREADY_EXISTS, "wrong error %u\n", GetLastError());
521 CloseHandle( handle2 );
522
523 SetLastError(0xdeadbeef);
524 handle2 = CreateEventA(NULL, FALSE, FALSE, __FILE__ ": TEST EVENT");
525 ok( handle2 != NULL, "CreateEvent failed with error %d\n", GetLastError());
526 ok( GetLastError() == 0, "wrong error %u\n", GetLastError());
527 CloseHandle( handle2 );
528
529 SetLastError(0xdeadbeef);
530 handle2 = OpenEventA( EVENT_ALL_ACCESS, FALSE, __FILE__ ": Test Event");
531 ok( handle2 != NULL, "OpenEvent failed with error %d\n", GetLastError());
532 CloseHandle( handle2 );
533
534 SetLastError(0xdeadbeef);
535 handle2 = OpenEventA( EVENT_ALL_ACCESS, FALSE, __FILE__ ": TEST EVENT");
536 ok( !handle2, "OpenEvent succeeded\n");
537 ok( GetLastError() == ERROR_FILE_NOT_FOUND, "wrong error %u\n", GetLastError());
538
539 SetLastError(0xdeadbeef);
540 handle2 = OpenEventA( EVENT_ALL_ACCESS, FALSE, NULL );
541 ok( !handle2, "OpenEvent succeeded\n");
542 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError());
543
544 SetLastError(0xdeadbeef);
545 handle2 = OpenEventW( EVENT_ALL_ACCESS, FALSE, NULL );
546 ok( !handle2, "OpenEvent succeeded\n");
547 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError());
548
549 CloseHandle( handle );
550
551 /* resource notifications are events too */
552
553 if (!pCreateMemoryResourceNotification || !pQueryMemoryResourceNotification)
554 {
555 trace( "memory resource notifications not supported\n" );
556 return;
557 }
558 handle = pCreateMemoryResourceNotification( HighMemoryResourceNotification + 1 );
559 ok( !handle, "CreateMemoryResourceNotification succeeded\n" );
560 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
561 ret = pQueryMemoryResourceNotification( handle, &val );
562 ok( !ret, "QueryMemoryResourceNotification succeeded\n" );
563 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
564
565 handle = pCreateMemoryResourceNotification( LowMemoryResourceNotification );
566 ok( handle != 0, "CreateMemoryResourceNotification failed err %u\n", GetLastError() );
567 ret = WaitForSingleObject( handle, 10 );
568 ok( ret == WAIT_OBJECT_0 || ret == WAIT_TIMEOUT, "WaitForSingleObject wrong ret %u\n", ret );
569
570 val = ~0;
571 ret = pQueryMemoryResourceNotification( handle, &val );
572 ok( ret, "QueryMemoryResourceNotification failed err %u\n", GetLastError() );
573 ok( val == FALSE || val == TRUE, "wrong value %u\n", val );
574 ret = CloseHandle( handle );
575 ok( ret, "CloseHandle failed err %u\n", GetLastError() );
576
577 handle = CreateEventA(NULL, FALSE, FALSE, __FILE__ ": Test Event");
578 val = ~0;
579 ret = pQueryMemoryResourceNotification( handle, &val );
580 ok( ret, "QueryMemoryResourceNotification failed err %u\n", GetLastError() );
581 ok( val == FALSE || val == TRUE, "wrong value %u\n", val );
582 CloseHandle( handle );
583 }
584
585 static void test_semaphore(void)
586 {
587 HANDLE handle, handle2;
588
589 /* test case sensitivity */
590
591 SetLastError(0xdeadbeef);
592 handle = CreateSemaphoreA(NULL, 0, 1, __FILE__ ": Test Semaphore");
593 ok(handle != NULL, "CreateSemaphore failed with error %u\n", GetLastError());
594 ok(GetLastError() == 0, "wrong error %u\n", GetLastError());
595
596 SetLastError(0xdeadbeef);
597 handle2 = CreateSemaphoreA(NULL, 0, 1, __FILE__ ": Test Semaphore");
598 ok( handle2 != NULL, "CreateSemaphore failed with error %d\n", GetLastError());
599 ok( GetLastError() == ERROR_ALREADY_EXISTS, "wrong error %u\n", GetLastError());
600 CloseHandle( handle2 );
601
602 SetLastError(0xdeadbeef);
603 handle2 = CreateSemaphoreA(NULL, 0, 1, __FILE__ ": TEST SEMAPHORE");
604 ok( handle2 != NULL, "CreateSemaphore failed with error %d\n", GetLastError());
605 ok( GetLastError() == 0, "wrong error %u\n", GetLastError());
606 CloseHandle( handle2 );
607
608 SetLastError(0xdeadbeef);
609 handle2 = OpenSemaphoreA( SEMAPHORE_ALL_ACCESS, FALSE, __FILE__ ": Test Semaphore");
610 ok( handle2 != NULL, "OpenSemaphore failed with error %d\n", GetLastError());
611 CloseHandle( handle2 );
612
613 SetLastError(0xdeadbeef);
614 handle2 = OpenSemaphoreA( SEMAPHORE_ALL_ACCESS, FALSE, __FILE__ ": TEST SEMAPHORE");
615 ok( !handle2, "OpenSemaphore succeeded\n");
616 ok( GetLastError() == ERROR_FILE_NOT_FOUND, "wrong error %u\n", GetLastError());
617
618 SetLastError(0xdeadbeef);
619 handle2 = OpenSemaphoreA( SEMAPHORE_ALL_ACCESS, FALSE, NULL );
620 ok( !handle2, "OpenSemaphore succeeded\n");
621 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError());
622
623 SetLastError(0xdeadbeef);
624 handle2 = OpenSemaphoreW( SEMAPHORE_ALL_ACCESS, FALSE, NULL );
625 ok( !handle2, "OpenSemaphore succeeded\n");
626 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError());
627
628 CloseHandle( handle );
629 }
630
631 static void test_waitable_timer(void)
632 {
633 HANDLE handle, handle2;
634
635 /* test case sensitivity */
636
637 SetLastError(0xdeadbeef);
638 handle = CreateWaitableTimerA(NULL, FALSE, __FILE__ ": Test WaitableTimer");
639 ok(handle != NULL, "CreateWaitableTimer failed with error %u\n", GetLastError());
640 ok(GetLastError() == 0, "wrong error %u\n", GetLastError());
641
642 SetLastError(0xdeadbeef);
643 handle2 = CreateWaitableTimerA(NULL, FALSE, __FILE__ ": Test WaitableTimer");
644 ok( handle2 != NULL, "CreateWaitableTimer failed with error %d\n", GetLastError());
645 ok( GetLastError() == ERROR_ALREADY_EXISTS, "wrong error %u\n", GetLastError());
646 CloseHandle( handle2 );
647
648 SetLastError(0xdeadbeef);
649 handle2 = CreateWaitableTimerA(NULL, FALSE, __FILE__ ": TEST WAITABLETIMER");
650 ok( handle2 != NULL, "CreateWaitableTimer failed with error %d\n", GetLastError());
651 ok( GetLastError() == 0, "wrong error %u\n", GetLastError());
652 CloseHandle( handle2 );
653
654 SetLastError(0xdeadbeef);
655 handle2 = OpenWaitableTimerA( TIMER_ALL_ACCESS, FALSE, __FILE__ ": Test WaitableTimer");
656 ok( handle2 != NULL, "OpenWaitableTimer failed with error %d\n", GetLastError());
657 CloseHandle( handle2 );
658
659 SetLastError(0xdeadbeef);
660 handle2 = OpenWaitableTimerA( TIMER_ALL_ACCESS, FALSE, __FILE__ ": TEST WAITABLETIMER");
661 ok( !handle2, "OpenWaitableTimer succeeded\n");
662 ok( GetLastError() == ERROR_FILE_NOT_FOUND, "wrong error %u\n", GetLastError());
663
664 SetLastError(0xdeadbeef);
665 handle2 = OpenWaitableTimerA( TIMER_ALL_ACCESS, FALSE, NULL );
666 ok( !handle2, "OpenWaitableTimer failed with error %d\n", GetLastError());
667 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError());
668
669 SetLastError(0xdeadbeef);
670 handle2 = OpenWaitableTimerW( TIMER_ALL_ACCESS, FALSE, NULL );
671 ok( !handle2, "OpenWaitableTimer failed with error %d\n", GetLastError());
672 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError());
673
674 CloseHandle( handle );
675 }
676
677 static HANDLE sem = 0;
678
679 static void CALLBACK iocp_callback(DWORD dwErrorCode, DWORD dwNumberOfBytesTransferred, LPOVERLAPPED lpOverlapped)
680 {
681 ReleaseSemaphore(sem, 1, NULL);
682 }
683
684 static BOOL (WINAPI *p_BindIoCompletionCallback)( HANDLE FileHandle, LPOVERLAPPED_COMPLETION_ROUTINE Function, ULONG Flags) = NULL;
685
686 static void test_iocp_callback(void)
687 {
688 char temp_path[MAX_PATH];
689 char filename[MAX_PATH];
690 DWORD ret;
691 BOOL retb;
692 static const char prefix[] = "pfx";
693 HANDLE hFile;
694 HMODULE hmod = GetModuleHandleA("kernel32.dll");
695 DWORD bytesWritten;
696 const char *buffer = "12345678123456781234567812345678";
697 OVERLAPPED overlapped;
698
699 p_BindIoCompletionCallback = (void*)GetProcAddress(hmod, "BindIoCompletionCallback");
700 if(!p_BindIoCompletionCallback) {
701 win_skip("BindIoCompletionCallback not found in this DLL\n");
702 return;
703 }
704
705 sem = CreateSemaphoreW(NULL, 0, 1, NULL);
706 ok(sem != INVALID_HANDLE_VALUE, "Creating a semaphore failed\n");
707
708 ret = GetTempPathA(MAX_PATH, temp_path);
709 ok(ret != 0, "GetTempPathA error %d\n", GetLastError());
710 ok(ret < MAX_PATH, "temp path should fit into MAX_PATH\n");
711
712 ret = GetTempFileNameA(temp_path, prefix, 0, filename);
713 ok(ret != 0, "GetTempFileNameA error %d\n", GetLastError());
714
715 hFile = CreateFileA(filename, GENERIC_READ | GENERIC_WRITE, 0, NULL,
716 CREATE_ALWAYS, FILE_FLAG_RANDOM_ACCESS, 0);
717 ok(hFile != INVALID_HANDLE_VALUE, "CreateFileA: error %d\n", GetLastError());
718
719 retb = p_BindIoCompletionCallback(hFile, iocp_callback, 0);
720 ok(retb == FALSE, "BindIoCompletionCallback succeeded on a file that wasn't created with FILE_FLAG_OVERLAPPED\n");
721 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Last error is %d\n", GetLastError());
722
723 ret = CloseHandle(hFile);
724 ok( ret, "CloseHandle: error %d\n", GetLastError());
725 ret = DeleteFileA(filename);
726 ok( ret, "DeleteFileA: error %d\n", GetLastError());
727
728 hFile = CreateFileA(filename, GENERIC_READ | GENERIC_WRITE, 0, NULL,
729 CREATE_ALWAYS, FILE_FLAG_RANDOM_ACCESS | FILE_FLAG_OVERLAPPED, 0);
730 ok(hFile != INVALID_HANDLE_VALUE, "CreateFileA: error %d\n", GetLastError());
731
732 retb = p_BindIoCompletionCallback(hFile, iocp_callback, 0);
733 ok(retb == TRUE, "BindIoCompletionCallback failed\n");
734
735 memset(&overlapped, 0, sizeof(overlapped));
736 retb = WriteFile(hFile, buffer, 4, &bytesWritten, &overlapped);
737 ok(retb == TRUE || GetLastError() == ERROR_IO_PENDING, "WriteFile failed, lastError = %d\n", GetLastError());
738
739 ret = WaitForSingleObject(sem, 5000);
740 ok(ret == WAIT_OBJECT_0, "Wait for the IO completion callback failed\n");
741 CloseHandle(sem);
742
743 retb = p_BindIoCompletionCallback(hFile, iocp_callback, 0);
744 ok(retb == FALSE, "BindIoCompletionCallback succeeded when setting the same callback on the file again\n");
745 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Last error is %d\n", GetLastError());
746 retb = p_BindIoCompletionCallback(hFile, NULL, 0);
747 ok(retb == FALSE, "BindIoCompletionCallback succeeded when setting the callback to NULL\n");
748 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Last error is %d\n", GetLastError());
749
750 ret = CloseHandle(hFile);
751 ok( ret, "CloseHandle: error %d\n", GetLastError());
752 ret = DeleteFileA(filename);
753 ok( ret, "DeleteFileA: error %d\n", GetLastError());
754
755 /* win2k3 requires the Flags parameter to be zero */
756 SetLastError(0xdeadbeef);
757 hFile = CreateFileA(filename, GENERIC_READ | GENERIC_WRITE, 0, NULL,
758 CREATE_ALWAYS, FILE_FLAG_RANDOM_ACCESS | FILE_FLAG_OVERLAPPED, 0);
759 ok(hFile != INVALID_HANDLE_VALUE, "CreateFileA: error %d\n", GetLastError());
760 retb = p_BindIoCompletionCallback(hFile, iocp_callback, 12345);
761 if (!retb)
762 ok(GetLastError() == ERROR_INVALID_PARAMETER,
763 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
764 else
765 ok(retb == TRUE, "BindIoCompletionCallback failed with Flags != 0\n");
766 ret = CloseHandle(hFile);
767 ok( ret, "CloseHandle: error %d\n", GetLastError());
768 ret = DeleteFileA(filename);
769 ok( ret, "DeleteFileA: error %d\n", GetLastError());
770
771 retb = p_BindIoCompletionCallback(NULL, iocp_callback, 0);
772 ok(retb == FALSE, "BindIoCompletionCallback succeeded on a NULL file\n");
773 ok(GetLastError() == ERROR_INVALID_HANDLE ||
774 GetLastError() == ERROR_INVALID_PARAMETER, /* vista */
775 "Last error is %d\n", GetLastError());
776 }
777
778 static void CALLBACK timer_queue_cb1(PVOID p, BOOLEAN timedOut)
779 {
780 int *pn = p;
781 ok(timedOut, "Timer callbacks should always time out\n");
782 ++*pn;
783 }
784
785 struct timer_queue_data1
786 {
787 int num_calls;
788 int max_calls;
789 HANDLE q, t;
790 };
791
792 static void CALLBACK timer_queue_cb2(PVOID p, BOOLEAN timedOut)
793 {
794 struct timer_queue_data1 *d = p;
795 ok(timedOut, "Timer callbacks should always time out\n");
796 if (d->t && ++d->num_calls == d->max_calls)
797 {
798 BOOL ret;
799 SetLastError(0xdeadbeef);
800 /* Note, XP SP2 does *not* do any deadlock checking, so passing
801 INVALID_HANDLE_VALUE here will just hang. */
802 ret = DeleteTimerQueueTimer(d->q, d->t, NULL);
803 ok(!ret, "DeleteTimerQueueTimer\n");
804 ok(GetLastError() == ERROR_IO_PENDING, "DeleteTimerQueueTimer\n");
805 }
806 }
807
808 static void CALLBACK timer_queue_cb3(PVOID p, BOOLEAN timedOut)
809 {
810 struct timer_queue_data1 *d = p;
811 ok(timedOut, "Timer callbacks should always time out\n");
812 if (d->t && ++d->num_calls == d->max_calls)
813 {
814 /* Basically kill the timer since it won't have time to run
815 again. */
816 BOOL ret = ChangeTimerQueueTimer(d->q, d->t, 10000, 0);
817 ok(ret, "ChangeTimerQueueTimer\n");
818 }
819 }
820
821 static void CALLBACK timer_queue_cb4(PVOID p, BOOLEAN timedOut)
822 {
823 struct timer_queue_data1 *d = p;
824 ok(timedOut, "Timer callbacks should always time out\n");
825 if (d->t)
826 {
827 /* This tests whether a timer gets flagged for deletion before
828 or after the callback runs. If we start this timer with a
829 period of zero (run once), then ChangeTimerQueueTimer will
830 fail if the timer is already flagged. Hence we really run
831 only once. Otherwise we will run multiple times. */
832 BOOL ret = ChangeTimerQueueTimer(d->q, d->t, 50, 50);
833 ok(ret, "ChangeTimerQueueTimer\n");
834 ++d->num_calls;
835 }
836 }
837
838 static void CALLBACK timer_queue_cb5(PVOID p, BOOLEAN timedOut)
839 {
840 DWORD_PTR delay = (DWORD_PTR) p;
841 ok(timedOut, "Timer callbacks should always time out\n");
842 if (delay)
843 Sleep(delay);
844 }
845
846 static void CALLBACK timer_queue_cb6(PVOID p, BOOLEAN timedOut)
847 {
848 struct timer_queue_data1 *d = p;
849 ok(timedOut, "Timer callbacks should always time out\n");
850 /* This tests an original implementation bug where a deleted timer may get
851 to run, but it is tricky to set up. */
852 if (d->q && d->num_calls++ == 0)
853 {
854 /* First run: delete ourselves, then insert and remove a timer
855 that goes in front of us in the sorted timeout list. Once
856 removed, we will still timeout at the faster timer's due time,
857 but this should be a no-op if we are bug-free. There should
858 not be a second run. We can test the value of num_calls later. */
859 BOOL ret;
860 HANDLE t;
861
862 /* The delete will pend while we are in this callback. */
863 SetLastError(0xdeadbeef);
864 ret = DeleteTimerQueueTimer(d->q, d->t, NULL);
865 ok(!ret, "DeleteTimerQueueTimer\n");
866 ok(GetLastError() == ERROR_IO_PENDING, "DeleteTimerQueueTimer\n");
867
868 ret = CreateTimerQueueTimer(&t, d->q, timer_queue_cb1, NULL, 100, 0, 0);
869 ok(ret, "CreateTimerQueueTimer\n");
870 ok(t != NULL, "CreateTimerQueueTimer\n");
871
872 ret = DeleteTimerQueueTimer(d->q, t, INVALID_HANDLE_VALUE);
873 ok(ret, "DeleteTimerQueueTimer\n");
874
875 /* Now we stay alive by hanging around in the callback. */
876 Sleep(500);
877 }
878 }
879
880 static void test_timer_queue(void)
881 {
882 HANDLE q, t0, t1, t2, t3, t4, t5;
883 int n0, n1, n2, n3, n4, n5;
884 struct timer_queue_data1 d1, d2, d3, d4;
885 HANDLE e, et1, et2;
886 BOOL ret, ret0;
887
888 /* Test asynchronous deletion of the queue. */
889 q = CreateTimerQueue();
890 ok(q != NULL, "CreateTimerQueue\n");
891
892 SetLastError(0xdeadbeef);
893 ret = DeleteTimerQueueEx(q, NULL);
894 ok(ret /* vista */ || GetLastError() == ERROR_IO_PENDING,
895 "DeleteTimerQueueEx, GetLastError: expected ERROR_IO_PENDING, got %d\n",
896 GetLastError());
897
898 /* Test synchronous deletion of the queue and running timers. */
899 q = CreateTimerQueue();
900 ok(q != NULL, "CreateTimerQueue\n");
901
902 /* Not called. */
903 t0 = NULL;
904 n0 = 0;
905 ret = CreateTimerQueueTimer(&t0, q, timer_queue_cb1, &n0, 0, 300, 0);
906 ok(ret, "CreateTimerQueueTimer\n");
907 ok(t0 != NULL, "CreateTimerQueueTimer\n");
908 ret0 = DeleteTimerQueueTimer(q, t0, NULL);
909 ok((!ret0 && GetLastError() == ERROR_IO_PENDING) ||
910 broken(ret0), /* Win 2000 & XP & 2003 */
911 "DeleteTimerQueueTimer ret=%d le=%u\n", ret0, GetLastError());
912
913 /* Called once. */
914 t1 = NULL;
915 n1 = 0;
916 ret = CreateTimerQueueTimer(&t1, q, timer_queue_cb1, &n1, 0, 0, 0);
917 ok(ret, "CreateTimerQueueTimer\n");
918 ok(t1 != NULL, "CreateTimerQueueTimer\n");
919
920 /* A slow one. */
921 t2 = NULL;
922 n2 = 0;
923 ret = CreateTimerQueueTimer(&t2, q, timer_queue_cb1, &n2, 0, 100, 0);
924 ok(ret, "CreateTimerQueueTimer\n");
925 ok(t2 != NULL, "CreateTimerQueueTimer\n");
926
927 /* A fast one. */
928 t3 = NULL;
929 n3 = 0;
930 ret = CreateTimerQueueTimer(&t3, q, timer_queue_cb1, &n3, 0, 10, 0);
931 ok(ret, "CreateTimerQueueTimer\n");
932 ok(t3 != NULL, "CreateTimerQueueTimer\n");
933
934 /* Start really late (it won't start). */
935 t4 = NULL;
936 n4 = 0;
937 ret = CreateTimerQueueTimer(&t4, q, timer_queue_cb1, &n4, 10000, 10, 0);
938 ok(ret, "CreateTimerQueueTimer\n");
939 ok(t4 != NULL, "CreateTimerQueueTimer\n");
940
941 /* Start soon, but delay so long it won't run again. */
942 t5 = NULL;
943 n5 = 0;
944 ret = CreateTimerQueueTimer(&t5, q, timer_queue_cb1, &n5, 0, 10000, 0);
945 ok(ret, "CreateTimerQueueTimer\n");
946 ok(t5 != NULL, "CreateTimerQueueTimer\n");
947
948 /* Give them a chance to do some work. */
949 Sleep(500);
950
951 /* Test deleting a once-only timer. */
952 ret = DeleteTimerQueueTimer(q, t1, INVALID_HANDLE_VALUE);
953 ok(ret, "DeleteTimerQueueTimer\n");
954
955 /* A periodic timer. */
956 ret = DeleteTimerQueueTimer(q, t2, INVALID_HANDLE_VALUE);
957 ok(ret, "DeleteTimerQueueTimer\n");
958
959 ret = DeleteTimerQueueEx(q, INVALID_HANDLE_VALUE);
960 ok(ret, "DeleteTimerQueueEx\n");
961 todo_wine
962 ok(n0 == 1 || broken(ret0 && n0 == 0), "Timer callback 0 expected 1 got %d\n", n0);
963 ok(n1 == 1, "Timer callback 1 expected 1 got %d\n", n1);
964 ok(n2 < n3, "Timer callback 2 & 3 expected %d < %d\n", n2, n3);
965 ok(n4 == 0, "Timer callback 4 expected 0 got %d\n", n4);
966 ok(n5 == 1, "Timer callback 5 expected 1 got %d\n", n5);
967
968 /* Test synchronous deletion of the timer/queue with event trigger. */
969 e = CreateEventW(NULL, TRUE, FALSE, NULL);
970 et1 = CreateEventW(NULL, TRUE, FALSE, NULL);
971 et2 = CreateEventW(NULL, TRUE, FALSE, NULL);
972 if (!e || !et1 || !et2)
973 {
974 skip("Failed to create timer queue descruction event\n");
975 return;
976 }
977
978 q = CreateTimerQueue();
979 ok(q != NULL, "CreateTimerQueue\n");
980
981 /* Run once and finish quickly (should be done when we delete it). */
982 t1 = NULL;
983 ret = CreateTimerQueueTimer(&t1, q, timer_queue_cb5, NULL, 0, 0, 0);
984 ok(ret, "CreateTimerQueueTimer\n");
985 ok(t1 != NULL, "CreateTimerQueueTimer\n");
986
987 /* Run once and finish slowly (shouldn't be done when we delete it). */
988 t2 = NULL;
989 ret = CreateTimerQueueTimer(&t2, q, timer_queue_cb5, (PVOID) 1000, 0, 0, 0);
990 ok(ret, "CreateTimerQueueTimer\n");
991 ok(t2 != NULL, "CreateTimerQueueTimer\n");
992
993 /* Run once and finish quickly (should be done when we delete it). */
994 t3 = NULL;
995 ret = CreateTimerQueueTimer(&t3, q, timer_queue_cb5, NULL, 0, 0, 0);
996 ok(ret, "CreateTimerQueueTimer\n");
997 ok(t3 != NULL, "CreateTimerQueueTimer\n");
998
999 /* Run once and finish slowly (shouldn't be done when we delete it). */
1000 t4 = NULL;
1001 ret = CreateTimerQueueTimer(&t4, q, timer_queue_cb5, (PVOID) 1000, 0, 0, 0);
1002 ok(ret, "CreateTimerQueueTimer\n");
1003 ok(t4 != NULL, "CreateTimerQueueTimer\n");
1004
1005 /* Give them a chance to start. */
1006 Sleep(400);
1007
1008 /* DeleteTimerQueueTimer always returns PENDING with a NULL event,
1009 even if the timer is finished. */
1010 SetLastError(0xdeadbeef);
1011 ret = DeleteTimerQueueTimer(q, t1, NULL);
1012 ok(ret /* vista */ || GetLastError() == ERROR_IO_PENDING,
1013 "DeleteTimerQueueTimer, GetLastError: expected ERROR_IO_PENDING, got %d\n",
1014 GetLastError());
1015
1016 SetLastError(0xdeadbeef);
1017 ret = DeleteTimerQueueTimer(q, t2, NULL);
1018 ok(!ret, "DeleteTimerQueueTimer call was expected to fail\n");
1019 ok(GetLastError() == ERROR_IO_PENDING,
1020 "DeleteTimerQueueTimer, GetLastError: expected ERROR_IO_PENDING, got %d\n",
1021 GetLastError());
1022
1023 SetLastError(0xdeadbeef);
1024 ret = DeleteTimerQueueTimer(q, t3, et1);
1025 ok(ret, "DeleteTimerQueueTimer call was expected to fail\n");
1026 ok(GetLastError() == 0xdeadbeef,
1027 "DeleteTimerQueueTimer, GetLastError: expected 0xdeadbeef, got %d\n",
1028 GetLastError());
1029 ok(WaitForSingleObject(et1, 250) == WAIT_OBJECT_0,
1030 "Timer destruction event not triggered\n");
1031
1032 SetLastError(0xdeadbeef);
1033 ret = DeleteTimerQueueTimer(q, t4, et2);
1034 ok(!ret, "DeleteTimerQueueTimer call was expected to fail\n");
1035 ok(GetLastError() == ERROR_IO_PENDING,
1036 "DeleteTimerQueueTimer, GetLastError: expected ERROR_IO_PENDING, got %d\n",
1037 GetLastError());
1038 ok(WaitForSingleObject(et2, 1000) == WAIT_OBJECT_0,
1039 "Timer destruction event not triggered\n");
1040
1041 SetLastError(0xdeadbeef);
1042 ret = DeleteTimerQueueEx(q, e);
1043 ok(ret /* vista */ || GetLastError() == ERROR_IO_PENDING,
1044 "DeleteTimerQueueEx, GetLastError: expected ERROR_IO_PENDING, got %d\n",
1045 GetLastError());
1046 ok(WaitForSingleObject(e, 250) == WAIT_OBJECT_0,
1047 "Queue destruction event not triggered\n");
1048 CloseHandle(e);
1049
1050 /* Test deleting/changing a timer in execution. */
1051 q = CreateTimerQueue();
1052 ok(q != NULL, "CreateTimerQueue\n");
1053
1054 /* Test changing a once-only timer before it fires (this is allowed,
1055 whereas after it fires you cannot). */
1056 n1 = 0;
1057 ret = CreateTimerQueueTimer(&t1, q, timer_queue_cb1, &n1, 10000, 0, 0);
1058 ok(ret, "CreateTimerQueueTimer\n");
1059 ok(t1 != NULL, "CreateTimerQueueTimer\n");
1060 ret = ChangeTimerQueueTimer(q, t1, 0, 0);
1061 ok(ret, "ChangeTimerQueueTimer\n");
1062
1063 d2.t = t2 = NULL;
1064 d2.num_calls = 0;
1065 d2.max_calls = 3;
1066 d2.q = q;
1067 ret = CreateTimerQueueTimer(&t2, q, timer_queue_cb2, &d2, 10, 10, 0);
1068 d2.t = t2;
1069 ok(ret, "CreateTimerQueueTimer\n");
1070 ok(t2 != NULL, "CreateTimerQueueTimer\n");
1071
1072 d3.t = t3 = NULL;
1073 d3.num_calls = 0;
1074 d3.max_calls = 4;
1075 d3.q = q;
1076 ret = CreateTimerQueueTimer(&t3, q, timer_queue_cb3, &d3, 10, 10, 0);
1077 d3.t = t3;
1078 ok(ret, "CreateTimerQueueTimer\n");
1079 ok(t3 != NULL, "CreateTimerQueueTimer\n");
1080
1081 d4.t = t4 = NULL;
1082 d4.num_calls = 0;
1083 d4.q = q;
1084 ret = CreateTimerQueueTimer(&t4, q, timer_queue_cb4, &d4, 10, 0, 0);
1085 d4.t = t4;
1086 ok(ret, "CreateTimerQueueTimer\n");
1087 ok(t4 != NULL, "CreateTimerQueueTimer\n");
1088
1089 Sleep(500);
1090
1091 ret = DeleteTimerQueueEx(q, INVALID_HANDLE_VALUE);
1092 ok(ret, "DeleteTimerQueueEx\n");
1093 ok(n1 == 1, "ChangeTimerQueueTimer\n");
1094 ok(d2.num_calls == d2.max_calls, "DeleteTimerQueueTimer\n");
1095 ok(d3.num_calls == d3.max_calls, "ChangeTimerQueueTimer\n");
1096 ok(d4.num_calls == 1, "Timer flagged for deletion incorrectly\n");
1097
1098 /* Test an obscure bug that was in the original implementation. */
1099 q = CreateTimerQueue();
1100 ok(q != NULL, "CreateTimerQueue\n");
1101
1102 /* All the work is done in the callback. */
1103 d1.t = t1 = NULL;
1104 d1.num_calls = 0;
1105 d1.q = q;
1106 ret = CreateTimerQueueTimer(&t1, q, timer_queue_cb6, &d1, 100, 100, WT_EXECUTELONGFUNCTION);
1107 d1.t = t1;
1108 ok(ret, "CreateTimerQueueTimer\n");
1109 ok(t1 != NULL, "CreateTimerQueueTimer\n");
1110
1111 Sleep(750);
1112
1113 SetLastError(0xdeadbeef);
1114 ret = DeleteTimerQueueEx(q, NULL);
1115 ok(ret /* vista */ || GetLastError() == ERROR_IO_PENDING,
1116 "DeleteTimerQueueEx, GetLastError: expected ERROR_IO_PENDING, got %d\n",
1117 GetLastError());
1118 ok(d1.num_calls == 1, "DeleteTimerQueueTimer\n");
1119
1120 /* Test functions on the default timer queue. */
1121 t1 = NULL;
1122 n1 = 0;
1123 ret = CreateTimerQueueTimer(&t1, NULL, timer_queue_cb1, &n1, 1000, 1000, 0);
1124 ok(ret, "CreateTimerQueueTimer, default queue\n");
1125 ok(t1 != NULL, "CreateTimerQueueTimer, default queue\n");
1126
1127 ret = ChangeTimerQueueTimer(NULL, t1, 2000, 2000);
1128 ok(ret, "ChangeTimerQueueTimer, default queue\n");
1129
1130 ret = DeleteTimerQueueTimer(NULL, t1, INVALID_HANDLE_VALUE);
1131 ok(ret, "DeleteTimerQueueTimer, default queue\n");
1132
1133 /* Try mixing default and non-default queues. Apparently this works. */
1134 q = CreateTimerQueue();
1135 ok(q != NULL, "CreateTimerQueue\n");
1136
1137 t1 = NULL;
1138 n1 = 0;
1139 ret = CreateTimerQueueTimer(&t1, q, timer_queue_cb1, &n1, 1000, 1000, 0);
1140 ok(ret, "CreateTimerQueueTimer\n");
1141 ok(t1 != NULL, "CreateTimerQueueTimer\n");
1142
1143 t2 = NULL;
1144 n2 = 0;
1145 ret = CreateTimerQueueTimer(&t2, NULL, timer_queue_cb1, &n2, 1000, 1000, 0);
1146 ok(ret, "CreateTimerQueueTimer\n");
1147 ok(t2 != NULL, "CreateTimerQueueTimer\n");
1148
1149 ret = ChangeTimerQueueTimer(NULL, t1, 2000, 2000);
1150 ok(ret, "ChangeTimerQueueTimer\n");
1151
1152 ret = ChangeTimerQueueTimer(q, t2, 2000, 2000);
1153 ok(ret, "ChangeTimerQueueTimer\n");
1154
1155 ret = DeleteTimerQueueTimer(NULL, t1, INVALID_HANDLE_VALUE);
1156 ok(ret, "DeleteTimerQueueTimer\n");
1157
1158 ret = DeleteTimerQueueTimer(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 = DeleteTimerQueueEx(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 = DeleteTimerQueueEx(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 pInitOnceInitialize = (void *)GetProcAddress(hdll, "InitOnceInitialize");
2649 pInitOnceExecuteOnce = (void *)GetProcAddress(hdll, "InitOnceExecuteOnce");
2650 pInitOnceBeginInitialize = (void *)GetProcAddress(hdll, "InitOnceBeginInitialize");
2651 pInitOnceComplete = (void *)GetProcAddress(hdll, "InitOnceComplete");
2652 pInitializeConditionVariable = (void *)GetProcAddress(hdll, "InitializeConditionVariable");
2653 pSleepConditionVariableCS = (void *)GetProcAddress(hdll, "SleepConditionVariableCS");
2654 pSleepConditionVariableSRW = (void *)GetProcAddress(hdll, "SleepConditionVariableSRW");
2655 pWakeAllConditionVariable = (void *)GetProcAddress(hdll, "WakeAllConditionVariable");
2656 pWakeConditionVariable = (void *)GetProcAddress(hdll, "WakeConditionVariable");
2657 pInitializeSRWLock = (void *)GetProcAddress(hdll, "InitializeSRWLock");
2658 pAcquireSRWLockExclusive = (void *)GetProcAddress(hdll, "AcquireSRWLockExclusive");
2659 pAcquireSRWLockShared = (void *)GetProcAddress(hdll, "AcquireSRWLockShared");
2660 pReleaseSRWLockExclusive = (void *)GetProcAddress(hdll, "ReleaseSRWLockExclusive");
2661 pReleaseSRWLockShared = (void *)GetProcAddress(hdll, "ReleaseSRWLockShared");
2662 pTryAcquireSRWLockExclusive = (void *)GetProcAddress(hdll, "Tr