[PATCH v4 8/8] server: Replace redundant send_socket status fields with force_async boolean field.
Jinoh Kang
jinoh.kang.kr at gmail.com
Thu Mar 3 07:30:49 CST 2022
The 'status' field of send_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 send_socket handler code a bit.
Signed-off-by: Jinoh Kang <jinoh.kang.kr at gmail.com>
---
Notes:
v1 -> v2:
- adjust patch for new field "data_size" in send_socket_request
v2 -> v3: no changes
v3 -> v4: no changes
dlls/ntdll/unix/socket.c | 8 ++------
server/protocol.def | 5 ++---
server/sock.c | 40 ++++++++--------------------------------
3 files changed, 12 insertions(+), 41 deletions(-)
diff --git a/dlls/ntdll/unix/socket.c b/dlls/ntdll/unix/socket.c
index ad03907523d..11ce652fed5 100644
--- a/dlls/ntdll/unix/socket.c
+++ b/dlls/ntdll/unix/socket.c
@@ -921,13 +921,10 @@ static NTSTATUS sock_send( HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc, voi
data_size += len;
}
- status = force_async ? STATUS_PENDING : STATUS_DEVICE_NOT_READY;
-
SERVER_START_REQ( send_socket )
{
req->data_size = data_size;
- req->status = status;
- req->total = 0;
+ req->force_async = force_async;
req->async = server_async( handle, &async->io, event, apc, apc_user, iosb_client_ptr(io) );
status = wine_server_call( req );
wait_handle = wine_server_ptr_handle( reply->wait );
@@ -1131,8 +1128,7 @@ static NTSTATUS sock_transmit( HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc,
SERVER_START_REQ( send_socket )
{
req->data_size = async->head_len + async->file_len + async->tail_len;
- req->status = STATUS_PENDING;
- req->total = 0;
+ req->force_async = 1;
req->async = server_async( handle, &async->io, event, apc, apc_user, iosb_client_ptr(io) );
status = wine_server_call( req );
wait_handle = wine_server_ptr_handle( reply->wait );
diff --git a/server/protocol.def b/server/protocol.def
index 334abb66a77..5d8038d58b9 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -1461,10 +1461,9 @@ enum server_fd_type
/* Perform a send on a socket */
@REQ(send_socket)
- data_size_t data_size; /* total number of bytes to send (>= total) */
+ data_size_t data_size; /* total number of bytes to send */
async_data_t async; /* async I/O parameters */
- unsigned int status; /* status of initial call */
- unsigned int total; /* number of bytes already sent */
+ int force_async; /* Force asynchronous mode? */
@REPLY
obj_handle_t wait; /* handle to wait on for blocking send */
unsigned int options; /* device open options */
diff --git a/server/sock.c b/server/sock.c
index e899695bb60..c742bd687a1 100644
--- a/server/sock.c
+++ b/server/sock.c
@@ -3492,7 +3492,7 @@ static void send_socket_initial_callback( void *private, struct async *async, st
DECL_HANDLER(send_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;
@@ -3500,32 +3500,11 @@ DECL_HANDLER(send_socket)
if (!sock) return;
fd = sock->fd;
- /* If we had a short write and the socket is nonblocking (and the client is
- * not trying to force the operation to be asynchronous), return success.
- * Windows actually refuses to send any data in this case, and returns
- * EWOULDBLOCK, but we have no way of doing that. */
- if (status == STATUS_DEVICE_NOT_READY && req->total && sock->nonblocking)
- status = STATUS_SUCCESS;
+ if (!req->force_async && !sock->nonblocking && is_fd_overlapped( fd ))
+ timeout = (timeout_t)sock->sndtimeo * -10000;
- /* send() returned EWOULDBLOCK or a short write, i.e. cannot send all data 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 WSASend*() with a valid OVERLAPPED
- * structure) and for the timeout not to be respected. */
- if (is_fd_overlapped( fd ))
- timeout = (timeout_t)sock->sndtimeo * -10000;
-
- status = STATUS_PENDING;
- }
-
- if ((status == STATUS_PENDING || status == STATUS_DEVICE_NOT_READY) && sock->wr_shutdown)
- status = STATUS_PIPE_DISCONNECTED;
-
- if ((status == STATUS_PENDING || status == STATUS_DEVICE_NOT_READY) && !async_queued( &sock->write_q ))
+ if (sock->wr_shutdown) status = STATUS_PIPE_DISCONNECTED;
+ else if (!async_queued( &sock->write_q ))
{
/* If write_q is not empty, we cannot really tell if the already queued
* asyncs will not consume all available space; if there's no space
@@ -3544,14 +3523,11 @@ DECL_HANDLER(send_socket)
}
}
+ if (status == STATUS_PENDING && !req->force_async && sock->nonblocking)
+ status = STATUS_DEVICE_NOT_READY;
+
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 );
async_set_initial_status_callback( async, send_socket_initial_callback, (void *)(unsigned long)req->data_size );
--
2.34.1
More information about the wine-devel
mailing list