[PATCH v3 2/2] ntdll: Cancel asyncs when thread is terminated.

Paul Gofman wine at gitlab.winehq.org
Fri Jun 3 15:12:07 CDT 2022


From: Paul Gofman <pgofman at codeweavers.com>

Signed-off-by: Paul Gofman <pgofman at codeweavers.com>
---
 dlls/ws2_32/tests/afd.c | 38 ++++++++++++++++----------------------
 server/async.c          |  5 +++++
 server/file.h           |  1 +
 server/thread.c         |  1 +
 4 files changed, 23 insertions(+), 22 deletions(-)

diff --git a/dlls/ws2_32/tests/afd.c b/dlls/ws2_32/tests/afd.c
index b8579a7c9f7..de042358297 100644
--- a/dlls/ws2_32/tests/afd.c
+++ b/dlls/ws2_32/tests/afd.c
@@ -2453,16 +2453,16 @@ static void test_async_thread_termination(void)
             IOCTL_AFD_POLL, in_params, params_size, out_params, params_size);
     ok(ret == STATUS_PENDING, "got %#x\n", ret);
     ret = WaitForSingleObject(event, 1000);
-    todo_wine ok(!ret, "got %#x\n", ret);
-    todo_wine ok(io.Status == STATUS_CANCELLED, "got %#lx\n", io.Status);
+    ok(!ret, "got %#x\n", ret);
+    ok(io.Status == STATUS_CANCELLED, "got %#lx\n", io.Status);
 
     memset(&io, 0xcc, sizeof(io));
     ret = thread_NtDeviceIoControlFile(FALSE, (HANDLE)listener, event, NULL, NULL, &io,
             IOCTL_AFD_POLL, in_params, params_size, out_params, params_size);
     ok(ret == STATUS_PENDING, "got %#x\n", ret);
     ret = WaitForSingleObject(event, 1000);
-    todo_wine ok(!ret, "got %#x\n", ret);
-    todo_wine ok(io.Status == STATUS_CANCELLED, "got %#lx\n", io.Status);
+    ok(!ret, "got %#x\n", ret);
+    ok(io.Status == STATUS_CANCELLED, "got %#lx\n", io.Status);
 
     port = CreateIoCompletionPort((HANDLE)listener, NULL, 0, 0);
 
@@ -2472,20 +2472,17 @@ static void test_async_thread_termination(void)
     ok(ret == STATUS_PENDING, "got %#x\n", ret);
 
     ret = WaitForSingleObject(event, 1000);
-    todo_wine ok(!ret, "got %#x\n", ret);
-    todo_wine ok(io.Status == STATUS_CANCELLED, "got %#lx\n", io.Status);
+    ok(!ret, "got %#x\n", ret);
+    ok(io.Status == STATUS_CANCELLED, "got %#lx\n", io.Status);
 
     memset(&io, 0xcc, sizeof(io));
     key = 0xcc;
     value = 0;
     ret = NtRemoveIoCompletion(port, &key, &value, &io, &zero);
-    todo_wine
-    {
-        ok(!ret, "got %#x\n", ret);
-        ok(!key, "got key %#Ix\n", key);
-        ok(value == 0xdeadbeef, "got value %#Ix\n", value);
-        ok(io.Status == STATUS_CANCELLED, "got %#lx\n", io.Status);
-    }
+    ok(!ret, "got %#x\n", ret);
+    ok(!key, "got key %#Ix\n", key);
+    ok(value == 0xdeadbeef, "got value %#Ix\n", value);
+    ok(io.Status == STATUS_CANCELLED, "got %#lx\n", io.Status);
 
     memset(&io, 0xcc, sizeof(io));
     ret = thread_NtDeviceIoControlFile(FALSE, (HANDLE)listener, event, NULL, (void *)0xdeadbeef, &io,
@@ -2493,20 +2490,17 @@ static void test_async_thread_termination(void)
     ok(ret == STATUS_PENDING, "got %#x\n", ret);
 
     ret = WaitForSingleObject(event, 1000);
-    todo_wine ok(!ret, "got %#x\n", ret);
-    todo_wine ok(io.Status == STATUS_CANCELLED, "got %#lx\n", io.Status);
+    ok(!ret, "got %#x\n", ret);
+    ok(io.Status == STATUS_CANCELLED, "got %#lx\n", io.Status);
 
     memset(&io, 0xcc, sizeof(io));
     key = 0xcc;
     value = 0;
     ret = NtRemoveIoCompletion(port, &key, &value, &io, &zero);
-    todo_wine
-    {
-        ok(!ret, "got %#x\n", ret);
-        ok(!key, "got key %#Ix\n", key);
-        ok(value == 0xdeadbeef, "got value %#Ix\n", value);
-        ok(io.Status == STATUS_CANCELLED, "got %#lx\n", io.Status);
-    }
+    ok(!ret, "got %#x\n", ret);
+    ok(!key, "got key %#Ix\n", key);
+    ok(value == 0xdeadbeef, "got value %#Ix\n", value);
+    ok(io.Status == STATUS_CANCELLED, "got %#lx\n", io.Status);
 
     CloseHandle(port);
     CloseHandle(event);
diff --git a/server/async.c b/server/async.c
index a4fbeab555e..57baef68137 100644
--- a/server/async.c
+++ b/server/async.c
@@ -593,6 +593,11 @@ void cancel_process_asyncs( struct process *process )
     cancel_async( process, NULL, NULL, 0 );
 }
 
+void cancel_terminating_thread_asyncs( struct thread *thread )
+{
+    cancel_async( thread->process, NULL, thread, 0 );
+}
+
 /* wake up async operations on the queue */
 void async_wake_up( struct async_queue *queue, unsigned int status )
 {
diff --git a/server/file.h b/server/file.h
index 9f9d4cd4e1a..0ffe0e2c8dc 100644
--- a/server/file.h
+++ b/server/file.h
@@ -245,6 +245,7 @@ extern struct iosb *async_get_iosb( struct async *async );
 extern struct thread *async_get_thread( struct async *async );
 extern struct async *find_pending_async( struct async_queue *queue );
 extern void cancel_process_asyncs( struct process *process );
+extern void cancel_terminating_thread_asyncs( struct thread *thread );
 
 static inline void init_async_queue( struct async_queue *queue )
 {
diff --git a/server/thread.c b/server/thread.c
index 467ccd1f0db..f49fbf40b78 100644
--- a/server/thread.c
+++ b/server/thread.c
@@ -1462,6 +1462,7 @@ DECL_HANDLER(terminate_thread)
         thread->exit_code = req->exit_code;
         if (thread != current) kill_thread( thread, 1 );
         else reply->self = 1;
+        cancel_terminating_thread_asyncs( thread );
         release_object( thread );
     }
 }
-- 
GitLab

https://gitlab.winehq.org/wine/wine/-/merge_requests/135



More information about the wine-devel mailing list