From cc0556df4a3bad49f7ffe55edf4197bd9f6f4a32 Mon Sep 17 00:00:00 2001 From: Sebastian Lackner Date: Fri, 9 Oct 2015 21:33:39 +0200 Subject: [PATCH] Added patch to fix handling of wait interrupted by User APC. --- README.md | 3 +- debian/changelog | 1 + ...dd-test-to-show-that-multiple-user-A.patch | 70 +++++++++++++++++++ ...ck-if-object-was-signaled-after-user.patch | 57 +++++++++++++++ patches/ntdll-Wait_User_APC/definition | 1 + patches/patchinstall.sh | 18 +++++ 6 files changed, 149 insertions(+), 1 deletion(-) create mode 100644 patches/ntdll-Wait_User_APC/0001-kernel32-tests-Add-test-to-show-that-multiple-user-A.patch create mode 100644 patches/ntdll-Wait_User_APC/0002-ntdll-Do-not-check-if-object-was-signaled-after-user.patch create mode 100644 patches/ntdll-Wait_User_APC/definition diff --git a/README.md b/README.md index 0270f098..55b352e4 100644 --- a/README.md +++ b/README.md @@ -34,8 +34,9 @@ Wine. All those differences are also documented on the Included bug fixes and improvements ----------------------------------- -**Bug fixes and features included in the next upcoming release [1]:** +**Bug fixes and features included in the next upcoming release [2]:** +* Do not check if object was signaled after user APC in server_select * Show windows version when collecting system info in winedbg diff --git a/debian/changelog b/debian/changelog index 89d4220c..984d6993 100644 --- a/debian/changelog +++ b/debian/changelog @@ -4,6 +4,7 @@ wine-staging (1.7.53) UNRELEASED; urgency=low * Added patch to show windows version when collecting system info in winedbg. * Added patch to implement DSPROPSETID_EAX20_ListenerProperties stub. * Added patch to implement DSPROPSETID_EAX20_BufferProperties stub. + * Added patch to fix handling of wait interrupted by User APC. * Removed patch to mark RegOpenKeyExA, RegCloseKey and RegQueryValueExA as hotpatchable (accepted upstream). * Removed patch to mark BitBlt and StretchDIBits as hotpatchable (accepted diff --git a/patches/ntdll-Wait_User_APC/0001-kernel32-tests-Add-test-to-show-that-multiple-user-A.patch b/patches/ntdll-Wait_User_APC/0001-kernel32-tests-Add-test-to-show-that-multiple-user-A.patch new file mode 100644 index 00000000..7ddf5221 --- /dev/null +++ b/patches/ntdll-Wait_User_APC/0001-kernel32-tests-Add-test-to-show-that-multiple-user-A.patch @@ -0,0 +1,70 @@ +From 7284f98729206e3d28732a7640f53fe75fe17c5c Mon Sep 17 00:00:00 2001 +From: Sebastian Lackner +Date: Fri, 9 Oct 2015 20:51:23 +0200 +Subject: kernel32/tests: Add test to show that multiple user APCs are + processed at once. + +--- + dlls/kernel32/tests/sync.c | 27 ++++++++++++++++++++++++++- + 1 file changed, 26 insertions(+), 1 deletion(-) + +diff --git a/dlls/kernel32/tests/sync.c b/dlls/kernel32/tests/sync.c +index e842bf3..173793c 100644 +--- a/dlls/kernel32/tests/sync.c ++++ b/dlls/kernel32/tests/sync.c +@@ -2333,6 +2333,13 @@ static DWORD WINAPI alertable_wait_thread(void *param) + todo_wine + ok(status == STATUS_WAIT_0, "expected STATUS_WAIT_0, got %08x\n", status); + ++ ReleaseSemaphore(semaphores[0], 1, NULL); ++ timeout.QuadPart = -10000000; ++ status = pNtWaitForMultipleObjects(1, &semaphores[1], FALSE, TRUE, &timeout); ++ ok(status == STATUS_USER_APC, "expected STATUS_USER_APC, got %08x\n", status); ++ result = WaitForSingleObject(semaphores[0], 0); ++ ok(result == WAIT_TIMEOUT, "expected WAIT_TIMEOUT, got %u\n", result); ++ + return 0; + } + +@@ -2342,12 +2349,21 @@ static void CALLBACK alertable_wait_apc(ULONG_PTR userdata) + ReleaseSemaphore(semaphores[1], 1, NULL); + } + ++static void CALLBACK alertable_wait_apc2(ULONG_PTR userdata) ++{ ++ HANDLE *semaphores = (void *)userdata; ++ DWORD result; ++ ++ result = WaitForSingleObject(semaphores[0], 1000); ++ ok(result == WAIT_OBJECT_0, "expected WAIT_OBJECT_0, got %u\n", result); ++} ++ + static void test_alertable_wait(void) + { + HANDLE thread, semaphores[2]; + DWORD result; + +- semaphores[0] = CreateSemaphoreW(NULL, 0, 1, NULL); ++ semaphores[0] = CreateSemaphoreW(NULL, 0, 2, NULL); + ok(semaphores[0] != NULL, "CreateSemaphore failed with %u\n", GetLastError()); + semaphores[1] = CreateSemaphoreW(NULL, 0, 1, NULL); + ok(semaphores[1] != NULL, "CreateSemaphore failed with %u\n", GetLastError()); +@@ -2366,6 +2382,15 @@ static void test_alertable_wait(void) + result = QueueUserAPC(alertable_wait_apc, thread, (ULONG_PTR)semaphores); + ok(result != 0, "QueueUserAPC failed with %u\n", GetLastError()); + ++ result = WaitForSingleObject(semaphores[0], 1000); ++ ok(result == WAIT_OBJECT_0, "expected WAIT_OBJECT_0, got %u\n", result); ++ Sleep(100); /* ensure the thread is blocking in NtWaitForMultipleObjects */ ++ result = QueueUserAPC(alertable_wait_apc2, thread, (ULONG_PTR)semaphores); ++ ok(result != 0, "QueueUserAPC failed with %u\n", GetLastError()); ++ result = QueueUserAPC(alertable_wait_apc2, thread, (ULONG_PTR)semaphores); ++ ok(result != 0, "QueueUserAPC failed with %u\n", GetLastError()); ++ ReleaseSemaphore(semaphores[0], 2, NULL); ++ + result = WaitForSingleObject(thread, 1000); + ok(result == WAIT_OBJECT_0, "expected WAIT_OBJECT_0, got %u\n", result); + CloseHandle(thread); +-- +2.6.0 + diff --git a/patches/ntdll-Wait_User_APC/0002-ntdll-Do-not-check-if-object-was-signaled-after-user.patch b/patches/ntdll-Wait_User_APC/0002-ntdll-Do-not-check-if-object-was-signaled-after-user.patch new file mode 100644 index 00000000..6373fba6 --- /dev/null +++ b/patches/ntdll-Wait_User_APC/0002-ntdll-Do-not-check-if-object-was-signaled-after-user.patch @@ -0,0 +1,57 @@ +From e87ab2e2a235d7f70aa414bb7f103f9ecb214cec Mon Sep 17 00:00:00 2001 +From: Sebastian Lackner +Date: Fri, 9 Oct 2015 21:12:59 +0200 +Subject: ntdll: Do not check if object was signaled after user APC in + server_select. + +--- + dlls/kernel32/tests/sync.c | 4 ---- + dlls/ntdll/server.c | 5 +++-- + 2 files changed, 3 insertions(+), 6 deletions(-) + +diff --git a/dlls/kernel32/tests/sync.c b/dlls/kernel32/tests/sync.c +index 173793c..1065d5e 100644 +--- a/dlls/kernel32/tests/sync.c ++++ b/dlls/kernel32/tests/sync.c +@@ -2317,20 +2317,16 @@ static DWORD WINAPI alertable_wait_thread(void *param) + + ReleaseSemaphore(semaphores[0], 1, NULL); + result = WaitForMultipleObjectsEx(1, &semaphores[1], TRUE, 1000, TRUE); +- todo_wine + ok(result == WAIT_IO_COMPLETION, "expected WAIT_IO_COMPLETION, got %u\n", result); + result = WaitForMultipleObjectsEx(1, &semaphores[1], TRUE, 200, TRUE); +- todo_wine + ok(result == WAIT_OBJECT_0, "expected WAIT_OBJECT_0, got %u\n", result); + + ReleaseSemaphore(semaphores[0], 1, NULL); + timeout.QuadPart = -10000000; + status = pNtWaitForMultipleObjects(1, &semaphores[1], FALSE, TRUE, &timeout); +- todo_wine + ok(status == STATUS_USER_APC, "expected STATUS_USER_APC, got %08x\n", status); + timeout.QuadPart = -2000000; + status = pNtWaitForMultipleObjects(1, &semaphores[1], FALSE, TRUE, &timeout); +- todo_wine + ok(status == STATUS_WAIT_0, "expected STATUS_WAIT_0, got %08x\n", status); + + ReleaseSemaphore(semaphores[0], 1, NULL); +diff --git a/dlls/ntdll/server.c b/dlls/ntdll/server.c +index 95111ad..7d8d1e9 100644 +--- a/dlls/ntdll/server.c ++++ b/dlls/ntdll/server.c +@@ -614,10 +614,11 @@ unsigned int server_select( const select_op_t *select_op, data_size_t size, UINT + if (ret != STATUS_USER_APC) break; + if (invoke_apc( &call, &result )) + { +- /* if we ran a user apc we have to check once more if an object got signaled, +- * but we don't want to wait */ ++ /* if we ran a user apc, we have to check once more if ++ * additional apcs are queued, but we don't want to wait */ + abs_timeout = 0; + user_apc = TRUE; ++ size = 0; + } + + /* don't signal multiple times */ +-- +2.6.0 + diff --git a/patches/ntdll-Wait_User_APC/definition b/patches/ntdll-Wait_User_APC/definition new file mode 100644 index 00000000..40d2b6e7 --- /dev/null +++ b/patches/ntdll-Wait_User_APC/definition @@ -0,0 +1 @@ +Fixes: Do not check if object was signaled after user APC in server_select diff --git a/patches/patchinstall.sh b/patches/patchinstall.sh index a42c3669..7fd6da91 100755 --- a/patches/patchinstall.sh +++ b/patches/patchinstall.sh @@ -209,6 +209,7 @@ patch_enable_all () enable_ntdll_User_Shared_Data="$1" enable_ntdll_Virtual_Memory_Stack="$1" enable_ntdll_WRITECOPY="$1" + enable_ntdll_Wait_User_APC="$1" enable_ntdll_WinSqm="$1" enable_ntdll_WriteWatches="$1" enable_ntdll_Zero_mod_name="$1" @@ -720,6 +721,9 @@ patch_enable () ntdll-WRITECOPY) enable_ntdll_WRITECOPY="$2" ;; + ntdll-Wait_User_APC) + enable_ntdll_Wait_User_APC="$2" + ;; ntdll-WinSqm) enable_ntdll_WinSqm="$2" ;; @@ -4280,6 +4284,20 @@ if test "$enable_ntdll_User_Shared_Data" -eq 1; then ) >> "$patchlist" fi +# Patchset ntdll-Wait_User_APC +# | +# | Modified files: +# | * dlls/kernel32/tests/sync.c, dlls/ntdll/server.c +# | +if test "$enable_ntdll_Wait_User_APC" -eq 1; then + patch_apply ntdll-Wait_User_APC/0001-kernel32-tests-Add-test-to-show-that-multiple-user-A.patch + patch_apply ntdll-Wait_User_APC/0002-ntdll-Do-not-check-if-object-was-signaled-after-user.patch + ( + echo '+ { "Sebastian Lackner", "kernel32/tests: Add test to show that multiple user APCs are processed at once.", 1 },'; + echo '+ { "Sebastian Lackner", "ntdll: Do not check if object was signaled after user APC in server_select.", 1 },'; + ) >> "$patchlist" +fi + # Patchset ntdll-WinSqm # | # | This patchset fixes the following Wine bugs: