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