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

Alexandre Julliard julliard at winehq.org
Fri Sep 3 16:25:29 CDT 2021


Module: wine
Branch: master
Commit: 15b8f91e247ef7a8838c377da1d7457eec02eb08
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=15b8f91e247ef7a8838c377da1d7457eec02eb08

Author: Zebediah Figura <zfigura at codeweavers.com>
Date:   Thu Sep  2 19:08:49 2021 -0500

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 at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/ws2_32/tests/sock.c |  4 ++--
 server/async.c           |  4 ++--
 server/fd.c              | 15 ++++++++++-----
 server/file.h            |  2 +-
 server/sock.c            | 34 ++++++++++------------------------
 5 files changed, 25 insertions(+), 34 deletions(-)

diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c
index ec010acebc6..8cbb393b542 100644
--- a/dlls/ws2_32/tests/sock.c
+++ b/dlls/ws2_32/tests/sock.c
@@ -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;
 
diff --git a/server/async.c b/server/async.c
index 4e9f3253759..50cb47dec92 100644
--- a/server/async.c
+++ b/server/async.c
@@ -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;
diff --git a/server/fd.c b/server/fd.c
index a09fc9edfcf..e4ef29806f2 100644
--- a/server/fd.c
+++ b/server/fd.c
@@ -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 );
     }
diff --git a/server/file.h b/server/file.h
index 9b8a620359e..592ee6b4e6b 100644
--- a/server/file.h
+++ b/server/file.h
@@ -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 );
diff --git a/server/sock.c b/server/sock.c
index bf109eb781a..fc181e85744 100644
--- a/server/sock.c
+++ b/server/sock.c
@@ -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 );
     }




More information about the wine-cvs mailing list