[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