Zebediah Figura : server: Do not signal completion if the async failed synchronously.
Alexandre Julliard
julliard at winehq.org
Mon Sep 13 16:12:33 CDT 2021
Module: wine
Branch: master
Commit: 4a73fbbd4059a950a1cb976087b0ec29712cad90
URL: https://source.winehq.org/git/wine.git/?a=commit;h=4a73fbbd4059a950a1cb976087b0ec29712cad90
Author: Zebediah Figura <zfigura at codeweavers.com>
Date: Sun Sep 12 16:07:53 2021 -0500
server: Do not signal completion if the async failed synchronously.
Signed-off-by: Zebediah Figura <zfigura at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/ntoskrnl.exe/tests/ntoskrnl.c | 14 +++++++-------
server/async.c | 39 ++++++++++++++++++++++----------------
2 files changed, 30 insertions(+), 23 deletions(-)
diff --git a/dlls/ntoskrnl.exe/tests/ntoskrnl.c b/dlls/ntoskrnl.exe/tests/ntoskrnl.c
index 49498a5e0e8..bd34e37e176 100644
--- a/dlls/ntoskrnl.exe/tests/ntoskrnl.c
+++ b/dlls/ntoskrnl.exe/tests/ntoskrnl.c
@@ -729,7 +729,7 @@ static void do_return_status(ULONG ioctl, struct return_status_params *params)
todo_wine ok(io.Status == 0xdeadf00d, "got %#x\n", io.Status);
todo_wine ok(io.Information == 0xdeadf00d, "got size %Iu\n", io.Information);
ret = WaitForSingleObject(event, 0);
- todo_wine ok(ret == WAIT_TIMEOUT, "got %d\n", ret);
+ ok(ret == WAIT_TIMEOUT, "got %d\n", ret);
}
else
{
@@ -753,7 +753,7 @@ static void do_return_status(ULONG ioctl, struct return_status_params *params)
ret = NtRemoveIoCompletion(port, &key, &value, &io, &zero);
if (!params->pending && NT_ERROR(params->iosb_status))
{
- todo_wine ok(ret == STATUS_TIMEOUT, "got %#x\n", ret);
+ ok(ret == STATUS_TIMEOUT, "got %#x\n", ret);
}
else
{
@@ -781,7 +781,7 @@ static void do_return_status(ULONG ioctl, struct return_status_params *params)
todo_wine ok(io.Status == 0xdeadf00d, "got %#x\n", io.Status);
todo_wine ok(io.Information == 0xdeadf00d, "got size %Iu\n", io.Information);
ret = WaitForSingleObject(event, 0);
- todo_wine ok(ret == WAIT_TIMEOUT, "got %d\n", ret);
+ ok(ret == WAIT_TIMEOUT, "got %d\n", ret);
}
else
{
@@ -813,7 +813,7 @@ static void do_return_status(ULONG ioctl, struct return_status_params *params)
todo_wine ok(io.Status == 0xdeadf00d, "got %#x\n", io.Status);
todo_wine ok(io.Information == 0xdeadf00d, "got size %Iu\n", io.Information);
ret = WaitForSingleObject(file, 0);
- todo_wine ok(ret == WAIT_TIMEOUT, "got %d\n", ret);
+ ok(ret == WAIT_TIMEOUT, "got %d\n", ret);
}
else
{
@@ -849,7 +849,7 @@ static void do_return_status(ULONG ioctl, struct return_status_params *params)
todo_wine ok(io.Status == 0xdeadf00d, "got %#x\n", io.Status);
todo_wine ok(io.Information == 0xdeadf00d, "got size %Iu\n", io.Information);
ret = WaitForSingleObject(event, 0);
- todo_wine ok(ret == WAIT_TIMEOUT, "got %d\n", ret);
+ ok(ret == WAIT_TIMEOUT, "got %d\n", ret);
}
else
{
@@ -932,8 +932,8 @@ static void do_return_status(ULONG ioctl, struct return_status_params *params)
ret = SleepEx(0, TRUE);
if (!params->pending && NT_ERROR(params->iosb_status))
{
- todo_wine ok(!ret, "got %d\n", ret);
- todo_wine ok(!got_return_status_apc, "got %u APC calls\n", got_return_status_apc);
+ ok(!ret, "got %d\n", ret);
+ ok(!got_return_status_apc, "got %u APC calls\n", got_return_status_apc);
}
else
{
diff --git a/server/async.c b/server/async.c
index df30ae3c7da..7cffd24a18b 100644
--- a/server/async.c
+++ b/server/async.c
@@ -465,25 +465,32 @@ void async_set_result( struct object *obj, unsigned int status, apc_param_t tota
async->terminated = 1;
if (async->iosb) async->iosb->status = status;
- if (async->data.apc)
+ /* don't signal completion if the async failed synchronously
+ * this can happen if the initial status was unknown (i.e. for device files)
+ * note that we check the IOSB status here, not the initial status */
+ if (async->pending || !NT_ERROR( status ))
{
- apc_call_t data;
- memset( &data, 0, sizeof(data) );
- data.type = APC_USER;
- data.user.func = async->data.apc;
- data.user.args[0] = async->data.apc_context;
- data.user.args[1] = async->data.iosb;
- data.user.args[2] = 0;
- thread_queue_apc( NULL, async->thread, NULL, &data );
- }
- else if (async->data.apc_context && (async->pending ||
- !(async->comp_flags & FILE_SKIP_COMPLETION_PORT_ON_SUCCESS)))
- {
- add_async_completion( async, async->data.apc_context, status, total );
+ if (async->data.apc)
+ {
+ apc_call_t data;
+ memset( &data, 0, sizeof(data) );
+ data.type = APC_USER;
+ data.user.func = async->data.apc;
+ data.user.args[0] = async->data.apc_context;
+ data.user.args[1] = async->data.iosb;
+ data.user.args[2] = 0;
+ thread_queue_apc( NULL, async->thread, NULL, &data );
+ }
+ else if (async->data.apc_context && (async->pending ||
+ !(async->comp_flags & FILE_SKIP_COMPLETION_PORT_ON_SUCCESS)))
+ {
+ add_async_completion( async, async->data.apc_context, status, total );
+ }
+
+ if (async->event) set_event( async->event );
+ else if (async->fd) set_fd_signaled( async->fd, 1 );
}
- if (async->event) set_event( async->event );
- else if (async->fd) set_fd_signaled( async->fd, 1 );
if (!async->signaled)
{
async->signaled = 1;
More information about the wine-cvs
mailing list