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