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