Jinoh Kang : server: Replace redundant recv_socket status fields with force_async boolean field.

Alexandre Julliard julliard at winehq.org
Thu Feb 10 16:10:31 CST 2022


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

Author: Jinoh Kang <jinoh.kang.kr at gmail.com>
Date:   Thu Feb 10 01:18:11 2022 +0900

server: Replace redundant recv_socket status fields with force_async boolean field.

The 'status' field of recv_socket_request is always either
STATUS_PENDING or STATUS_DEVICE_NOT_READY, and the 'total' field is
always zero.

Replace the 'status' field with 'force_async' boolean field, and get rid
of the 'total' field entirely.

Also, clean up the recv_socket handler code a bit.

Signed-off-by: Jinoh Kang <jinoh.kang.kr at gmail.com>
Signed-off-by: Zebediah Figura <zfigura at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/ntdll/unix/socket.c       |  6 +-----
 include/wine/server_protocol.h |  6 +++---
 server/protocol.def            |  3 +--
 server/request.h               |  3 +--
 server/sock.c                  | 40 ++++++++++++----------------------------
 server/trace.c                 |  3 +--
 6 files changed, 19 insertions(+), 42 deletions(-)

diff --git a/dlls/ntdll/unix/socket.c b/dlls/ntdll/unix/socket.c
index 5e3c724f807..23059e3cff8 100644
--- a/dlls/ntdll/unix/socket.c
+++ b/dlls/ntdll/unix/socket.c
@@ -737,13 +737,9 @@ static NTSTATUS sock_recv( HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc, voi
         }
     }
 
-    status = force_async ? STATUS_PENDING : STATUS_DEVICE_NOT_READY;
-    information = 0;
-
     SERVER_START_REQ( recv_socket )
     {
-        req->status = status;
-        req->total  = information;
+        req->force_async = force_async;
         req->async  = server_async( handle, &async->io, event, apc, apc_user, iosb_client_ptr(io) );
         req->oob    = !!(unix_flags & MSG_OOB);
         status = wine_server_call( req );
diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h
index be63b290353..e32ef8e1479 100644
--- a/include/wine/server_protocol.h
+++ b/include/wine/server_protocol.h
@@ -1764,8 +1764,8 @@ struct recv_socket_request
     struct request_header __header;
     int          oob;
     async_data_t async;
-    unsigned int status;
-    unsigned int total;
+    int          force_async;
+    char __pad_60[4];
 };
 struct recv_socket_reply
 {
@@ -6284,7 +6284,7 @@ union generic_reply
 
 /* ### protocol_version begin ### */
 
-#define SERVER_PROTOCOL_VERSION 745
+#define SERVER_PROTOCOL_VERSION 746
 
 /* ### protocol_version end ### */
 
diff --git a/server/protocol.def b/server/protocol.def
index 5c0f9a86822..9d90544fa41 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -1451,8 +1451,7 @@ enum server_fd_type
 @REQ(recv_socket)
     int          oob;           /* are we receiving OOB data? */
     async_data_t async;         /* async I/O parameters */
-    unsigned int status;        /* status of initial call */
-    unsigned int total;         /* number of bytes already read */
+    int          force_async;   /* Force asynchronous mode? */
 @REPLY
     obj_handle_t wait;          /* handle to wait on for blocking recv */
     unsigned int options;       /* device open options */
diff --git a/server/request.h b/server/request.h
index 98e23bfd4ba..2c7889bd197 100644
--- a/server/request.h
+++ b/server/request.h
@@ -1044,8 +1044,7 @@ C_ASSERT( FIELD_OFFSET(struct unlock_file_request, count) == 24 );
 C_ASSERT( sizeof(struct unlock_file_request) == 32 );
 C_ASSERT( FIELD_OFFSET(struct recv_socket_request, oob) == 12 );
 C_ASSERT( FIELD_OFFSET(struct recv_socket_request, async) == 16 );
-C_ASSERT( FIELD_OFFSET(struct recv_socket_request, status) == 56 );
-C_ASSERT( FIELD_OFFSET(struct recv_socket_request, total) == 60 );
+C_ASSERT( FIELD_OFFSET(struct recv_socket_request, force_async) == 56 );
 C_ASSERT( sizeof(struct recv_socket_request) == 64 );
 C_ASSERT( FIELD_OFFSET(struct recv_socket_reply, wait) == 8 );
 C_ASSERT( FIELD_OFFSET(struct recv_socket_reply, options) == 12 );
diff --git a/server/sock.c b/server/sock.c
index 38aaaac9e39..91f98556552 100644
--- a/server/sock.c
+++ b/server/sock.c
@@ -3396,7 +3396,7 @@ struct object *create_socket_device( struct object *root, const struct unicode_s
 DECL_HANDLER(recv_socket)
 {
     struct sock *sock = (struct sock *)get_handle_obj( current->process, req->async.handle, 0, &sock_ops );
-    unsigned int status = req->status;
+    unsigned int status = STATUS_PENDING;
     timeout_t timeout = 0;
     struct async *async;
     struct fd *fd;
@@ -3404,29 +3404,16 @@ DECL_HANDLER(recv_socket)
     if (!sock) return;
     fd = sock->fd;
 
-    /* recv() returned EWOULDBLOCK, i.e. no data available yet */
-    if (status == STATUS_DEVICE_NOT_READY && !sock->nonblocking)
-    {
-        /* Set a timeout on the async if necessary.
-         *
-         * We want to do this *only* if the client gave us STATUS_DEVICE_NOT_READY.
-         * If the client gave us STATUS_PENDING, it expects the async to always
-         * block (it was triggered by WSARecv*() with a valid OVERLAPPED
-         * structure) and for the timeout not to be respected. */
-        if (is_fd_overlapped( fd ))
-            timeout = (timeout_t)sock->rcvtimeo * -10000;
-
-        status = STATUS_PENDING;
-    }
-
-    if ((status == STATUS_PENDING || status == STATUS_DEVICE_NOT_READY) && sock->rd_shutdown)
-        status = STATUS_PIPE_DISCONNECTED;
+    if (!req->force_async && !sock->nonblocking && is_fd_overlapped( fd ))
+        timeout = (timeout_t)sock->rcvtimeo * -10000;
 
-    /* NOTE: If read_q is not empty, we cannot really tell if the already queued asyncs
-     * NOTE: will not consume all available data; if there's no data available,
-     * NOTE: the current request won't be immediately satiable. */
-    if ((status == STATUS_PENDING || status == STATUS_DEVICE_NOT_READY) && !async_queued( &sock->read_q ))
+    if (sock->rd_shutdown) status = STATUS_PIPE_DISCONNECTED;
+    else if (!async_queued( &sock->read_q ))
     {
+        /* If read_q is not empty, we cannot really tell if the already queued
+         * asyncs will not consume all available data; if there's no data
+         * available, the current request won't be immediately satiable.
+         */
         struct pollfd pollfd;
         pollfd.fd = get_unix_fd( sock->fd );
         pollfd.events = req->oob ? POLLPRI : POLLIN;
@@ -3440,17 +3427,14 @@ DECL_HANDLER(recv_socket)
         }
     }
 
+    if (status == STATUS_PENDING && !req->force_async && sock->nonblocking)
+        status = STATUS_DEVICE_NOT_READY;
+
     sock->pending_events &= ~(req->oob ? AFD_POLL_OOB : AFD_POLL_READ);
     sock->reported_events &= ~(req->oob ? AFD_POLL_OOB : AFD_POLL_READ);
 
     if ((async = create_request_async( fd, get_fd_comp_flags( fd ), &req->async )))
     {
-        if (status == STATUS_SUCCESS)
-        {
-            struct iosb *iosb = async_get_iosb( async );
-            iosb->result = req->total;
-            release_object( iosb );
-        }
         set_error( status );
 
         if (timeout)
diff --git a/server/trace.c b/server/trace.c
index 1fb39d4f997..61e592b0ffa 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -2032,8 +2032,7 @@ static void dump_recv_socket_request( const struct recv_socket_request *req )
 {
     fprintf( stderr, " oob=%d", req->oob );
     dump_async_data( ", async=", &req->async );
-    fprintf( stderr, ", status=%08x", req->status );
-    fprintf( stderr, ", total=%08x", req->total );
+    fprintf( stderr, ", force_async=%d", req->force_async );
 }
 
 static void dump_recv_socket_reply( const struct recv_socket_reply *req )




More information about the wine-cvs mailing list