[RFC PATCH v5 5/5] server: Replace redundant recv_socket status fields with force_async boolean field.
Jinoh Kang
jinoh.kang.kr at gmail.com
Fri Feb 4 14:52:11 CST 2022
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>
---
Notes:
v3 -> v4: unchanged
v4 -> v5:
- rearrange conditional statements
- remove pending flag
- remove dead code "information = 0;"
dlls/ntdll/unix/socket.c | 6 +-----
server/protocol.def | 3 +--
server/sock.c | 30 ++++++++++++------------------
3 files changed, 14 insertions(+), 25 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/server/protocol.def b/server/protocol.def
index ebd3612df06..2e00601e2a5 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/sock.c b/server/sock.c
index a050966f42b..ba9cd4fa9a5 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,8 +3404,8 @@ 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)
+ /* Synchronous, *blocking* I/O requested? */
+ if (!req->force_async && !sock->nonblocking)
{
/* Set a timeout on the async if necessary.
*
@@ -3415,18 +3415,15 @@ DECL_HANDLER(recv_socket)
* 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;
-
- /* 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 +3437,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)
--
2.34.1
More information about the wine-devel
mailing list