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