server: Check the status code to determine whether the async has failed.

Instead of manually specifying success or failure.

Based on test_return_status() in ntoskrnl. The changes in this patch don't
affect device IRPs, but the tests show the heuristic that Windows uses, and in
practice it turns out to be correct for all known asyncs.

Signed-off-by: Zebediah Figura <zfigura@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Zebediah Figura 2021-09-02 19:08:49 -05:00 committed by Alexandre Julliard
parent 285700a526
commit 15b8f91e24
5 changed files with 25 additions and 34 deletions

View File

@ -1934,8 +1934,8 @@ static void test_ip_pktinfo(void)
todo_wine ok(WSAGetLastError() == ERROR_IO_PENDING, "got error %u\n", WSAGetLastError());
rc = SleepEx(1000, TRUE);
todo_wine ok(rc == WAIT_IO_COMPLETION, "got %d\n", rc);
todo_wine ok(got_ip_pktinfo_apc == 1, "apc was called %u times\n", got_ip_pktinfo_apc);
ok(rc == WAIT_IO_COMPLETION, "got %d\n", rc);
ok(got_ip_pktinfo_apc == 1, "apc was called %u times\n", got_ip_pktinfo_apc);
ok(hdr.dwFlags == MSG_CTRUNC, "got flags %#x\n", hdr.dwFlags);
got_ip_pktinfo_apc = 0;

View File

@ -296,7 +296,7 @@ void set_async_pending( struct async *async, int signal )
}
/* return async object status and wait handle to client */
obj_handle_t async_handoff( struct async *async, int success, data_size_t *result, int force_blocking )
obj_handle_t async_handoff( struct async *async, data_size_t *result, int force_blocking )
{
if (async->unknown_status)
{
@ -305,7 +305,7 @@ obj_handle_t async_handoff( struct async *async, int success, data_size_t *resul
return async->wait_handle;
}
if (!success)
if (!async->pending && NT_ERROR( get_error() ))
{
close_handle( async->thread->process, async->wait_handle );
async->wait_handle = 0;

View File

@ -2692,7 +2692,8 @@ DECL_HANDLER(flush)
if ((async = create_request_async( fd, fd->comp_flags, &req->async )))
{
reply->event = async_handoff( async, fd->fd_ops->flush( fd, async ), NULL, 1 );
fd->fd_ops->flush( fd, async );
reply->event = async_handoff( async, NULL, 1 );
release_object( async );
}
release_object( fd );
@ -2720,7 +2721,8 @@ DECL_HANDLER(get_volume_info)
if ((async = create_request_async( fd, fd->comp_flags, &req->async )))
{
reply->wait = async_handoff( async, fd->fd_ops->get_volume_info( fd, async, req->info_class ), NULL, 1 );
fd->fd_ops->get_volume_info( fd, async, req->info_class );
reply->wait = async_handoff( async, NULL, 1 );
release_object( async );
}
release_object( fd );
@ -2795,7 +2797,8 @@ DECL_HANDLER(read)
if ((async = create_request_async( fd, fd->comp_flags, &req->async )))
{
reply->wait = async_handoff( async, fd->fd_ops->read( fd, async, req->pos ), NULL, 0 );
fd->fd_ops->read( fd, async, req->pos );
reply->wait = async_handoff( async, NULL, 0 );
reply->options = fd->options;
release_object( async );
}
@ -2812,7 +2815,8 @@ DECL_HANDLER(write)
if ((async = create_request_async( fd, fd->comp_flags, &req->async )))
{
reply->wait = async_handoff( async, fd->fd_ops->write( fd, async, req->pos ), &reply->size, 0 );
fd->fd_ops->write( fd, async, req->pos );
reply->wait = async_handoff( async, &reply->size, 0 );
reply->options = fd->options;
release_object( async );
}
@ -2830,7 +2834,8 @@ DECL_HANDLER(ioctl)
if ((async = create_request_async( fd, fd->comp_flags, &req->async )))
{
reply->wait = async_handoff( async, fd->fd_ops->ioctl( fd, req->code, async ), NULL, 0 );
fd->fd_ops->ioctl( fd, req->code, async );
reply->wait = async_handoff( async, NULL, 0 );
reply->options = fd->options;
release_object( async );
}

View File

@ -219,7 +219,7 @@ typedef void (*async_completion_callback)( void *private );
extern void free_async_queue( struct async_queue *queue );
extern struct async *create_async( struct fd *fd, struct thread *thread, const async_data_t *data, struct iosb *iosb );
extern struct async *create_request_async( struct fd *fd, unsigned int comp_flags, const async_data_t *data );
extern obj_handle_t async_handoff( struct async *async, int success, data_size_t *result, int force_blocking );
extern obj_handle_t async_handoff( struct async *async, data_size_t *result, int force_blocking );
extern void queue_async( struct async_queue *queue, struct async *async );
extern void async_set_timeout( struct async *async, timeout_t timeout, unsigned int status );
extern void async_set_result( struct object *obj, unsigned int status, apc_param_t total );

View File

@ -2839,8 +2839,8 @@ static int poll_single_socket( struct sock *sock, int mask )
return get_poll_flags( sock, pollfd.revents ) & mask;
}
static int poll_socket( struct sock *poll_sock, struct async *async, timeout_t timeout,
unsigned int count, const struct poll_socket_input *input )
static void poll_socket( struct sock *poll_sock, struct async *async, timeout_t timeout,
unsigned int count, const struct poll_socket_input *input )
{
struct poll_socket_output *output;
BOOL signaled = FALSE;
@ -2848,13 +2848,13 @@ static int poll_socket( struct sock *poll_sock, struct async *async, timeout_t t
unsigned int i, j;
if (!(output = mem_alloc( count * sizeof(*output) )))
return 0;
return;
memset( output, 0, count * sizeof(*output) );
if (!(req = mem_alloc( offsetof( struct poll_req, sockets[count] ) )))
{
free( output );
return 0;
return;
}
req->timeout = NULL;
@ -2863,7 +2863,7 @@ static int poll_socket( struct sock *poll_sock, struct async *async, timeout_t t
{
free( req );
free( output );
return 0;
return;
}
for (i = 0; i < count; ++i)
@ -2875,7 +2875,7 @@ static int poll_socket( struct sock *poll_sock, struct async *async, timeout_t t
if (req->timeout) remove_timeout_user( req->timeout );
free( req );
free( output );
return 0;
return;
}
req->sockets[i].flags = input[i].flags;
}
@ -2917,7 +2917,6 @@ static int poll_socket( struct sock *poll_sock, struct async *async, timeout_t t
for (i = 0; i < req->count; ++i)
sock_reselect( req->sockets[i].sock );
set_error( STATUS_PENDING );
return 1;
}
#ifdef HAVE_LINUX_RTNETLINK_H
@ -3249,18 +3248,11 @@ DECL_HANDLER(recv_socket)
if ((async = create_request_async( fd, get_fd_comp_flags( fd ), &req->async )))
{
int success = 0;
if (status == STATUS_SUCCESS)
{
struct iosb *iosb = async_get_iosb( async );
iosb->result = req->total;
release_object( iosb );
success = 1;
}
else if (status == STATUS_PENDING)
{
success = 1;
}
set_error( status );
@ -3273,7 +3265,7 @@ DECL_HANDLER(recv_socket)
/* always reselect; we changed reported_events above */
sock_reselect( sock );
reply->wait = async_handoff( async, success, NULL, 0 );
reply->wait = async_handoff( async, NULL, 0 );
reply->options = get_fd_options( fd );
release_object( async );
}
@ -3293,7 +3285,8 @@ DECL_HANDLER(poll_socket)
if ((async = create_request_async( sock->fd, get_fd_comp_flags( sock->fd ), &req->async )))
{
reply->wait = async_handoff( async, poll_socket( sock, async, req->timeout, count, input ), NULL, 0 );
poll_socket( sock, async, req->timeout, count, input );
reply->wait = async_handoff( async, NULL, 0 );
reply->options = get_fd_options( sock->fd );
release_object( async );
}
@ -3357,18 +3350,11 @@ DECL_HANDLER(send_socket)
if ((async = create_request_async( fd, get_fd_comp_flags( fd ), &req->async )))
{
int success = 0;
if (status == STATUS_SUCCESS)
{
struct iosb *iosb = async_get_iosb( async );
iosb->result = req->total;
release_object( iosb );
success = 1;
}
else if (status == STATUS_PENDING)
{
success = 1;
}
set_error( status );
@ -3381,7 +3367,7 @@ DECL_HANDLER(send_socket)
/* always reselect; we changed reported_events above */
sock_reselect( sock );
reply->wait = async_handoff( async, success, NULL, 0 );
reply->wait = async_handoff( async, NULL, 0 );
reply->options = get_fd_options( fd );
release_object( async );
}