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