server: Do not signal completion if the async failed synchronously.
Signed-off-by: Zebediah Figura <zfigura@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
097685aa9e
commit
4a73fbbd40
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue