[PATCH 4/9] server: Check the status code to determine whether the async has failed.

Zebediah Figura zfigura at codeweavers.com
Thu Sep 2 19:08:49 CDT 2021


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>
---
 server/async.c |  4 ++--
 server/fd.c    | 15 ++++++++++-----
 server/file.h  |  2 +-
 server/sock.c  | 34 ++++++++++------------------------
 4 files changed, 23 insertions(+), 32 deletions(-)

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 );
     }
-- 
2.33.0




More information about the wine-devel mailing list