Module: wine Branch: master Commit: d6d6ce299f3558a30cc5e09c8fe669f1be45a330 URL: http://source.winehq.org/git/wine.git/?a=commit;h=d6d6ce299f3558a30cc5e09c8f...
Author: Misha Koshelev mk144210@bcm.tmc.edu Date: Sat Feb 3 13:26:29 2007 -0600
kernel32: Added conformance test for nested thread wakeups in the server.
---
dlls/kernel32/tests/change.c | 46 ++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 46 insertions(+), 0 deletions(-)
diff --git a/dlls/kernel32/tests/change.c b/dlls/kernel32/tests/change.c index bf7cdc1..0774caf 100644 --- a/dlls/kernel32/tests/change.c +++ b/dlls/kernel32/tests/change.c @@ -317,6 +317,48 @@ static void test_ffcn(void) ok( r == TRUE, "failed to remove dir\n"); }
+/* this test concentrates on the wait behavior when multiple threads are + * waiting on a change notification handle. */ +static void test_ffcnMultipleThreads() +{ + LONG r; + DWORD filter, threadId, status, exitcode; + HANDLE handles[2]; + char path[MAX_PATH]; + + r = GetTempPathA(MAX_PATH, path); + ok(r, "GetTempPathA error: %d\n", GetLastError()); + + lstrcatA(path, "ffcnTestMultipleThreads"); + + RemoveDirectoryA(path); + + r = CreateDirectoryA(path, NULL); + ok(r, "CreateDirectoryA error: %d\n", GetLastError()); + + filter = FILE_NOTIFY_CHANGE_FILE_NAME; + filter |= FILE_NOTIFY_CHANGE_DIR_NAME; + + handles[0] = FindFirstChangeNotificationA(path, FALSE, filter); + ok(handles[0] != INVALID_HANDLE_VALUE, "FindFirstChangeNotification error: %d\n", GetLastError()); + + /* Test behavior if a waiting thread holds the last reference to a change + * directory object with an empty wine user APC queue for this thread (bug #7286) */ + + /* Create our notification thread */ + handles[1] = CreateThread(NULL, 0, NotificationThread, (LPVOID)handles[0], + 0, &threadId); + ok(handles[1] != NULL, "CreateThread error: %d\n", GetLastError()); + + status = WaitForMultipleObjects(2, handles, FALSE, 5000); + ok(status == WAIT_OBJECT_0 || status == WAIT_OBJECT_0+1, "WaitForMultipleObjects status %d error %d\n", status, GetLastError()); + ok(GetExitCodeThread(handles[1], &exitcode), "Could not retrieve thread exit code\n"); + + /* Clean up */ + r = RemoveDirectoryA( path ); + ok( r == TRUE, "failed to remove dir\n"); +} + typedef BOOL (WINAPI *fnReadDirectoryChangesW)(HANDLE,LPVOID,DWORD,BOOL,DWORD, LPDWORD,LPOVERLAPPED,LPOVERLAPPED_COMPLETION_ROUTINE); fnReadDirectoryChangesW pReadDirectoryChangesW; @@ -708,6 +750,10 @@ START_TEST(change) pReadDirectoryChangesW = (fnReadDirectoryChangesW) GetProcAddress(hkernel32, "ReadDirectoryChangesW");
+ test_ffcnMultipleThreads(); + /* The above function runs a test that must occur before FindCloseChangeNotification is run in the + current thread to preserve the emptiness of the wine user APC queue. To ensure this it should be + placed first. */ test_FindFirstChangeNotification(); test_ffcn(); test_readdirectorychanges();