server: Replace redundant send_socket status fields with force_async boolean field.
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@gmail.com> Signed-off-by: Zebediah Figura <zfigura@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
74059d12b8
commit
731a968003
6 changed files with 19 additions and 45 deletions
|
@ -908,12 +908,9 @@ static NTSTATUS sock_send( HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc, voi
|
|||
async->iov_cursor = 0;
|
||||
async->sent_len = 0;
|
||||
|
||||
status = force_async ? STATUS_PENDING : STATUS_DEVICE_NOT_READY;
|
||||
|
||||
SERVER_START_REQ( send_socket )
|
||||
{
|
||||
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 );
|
||||
|
@ -1116,8 +1113,7 @@ static NTSTATUS sock_transmit( HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc,
|
|||
|
||||
SERVER_START_REQ( send_socket )
|
||||
{
|
||||
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 );
|
||||
|
|
|
@ -1783,8 +1783,8 @@ struct send_socket_request
|
|||
struct request_header __header;
|
||||
char __pad_12[4];
|
||||
async_data_t async;
|
||||
unsigned int status;
|
||||
unsigned int total;
|
||||
int force_async;
|
||||
char __pad_60[4];
|
||||
};
|
||||
struct send_socket_reply
|
||||
{
|
||||
|
@ -6286,7 +6286,7 @@ union generic_reply
|
|||
|
||||
/* ### protocol_version begin ### */
|
||||
|
||||
#define SERVER_PROTOCOL_VERSION 748
|
||||
#define SERVER_PROTOCOL_VERSION 749
|
||||
|
||||
/* ### protocol_version end ### */
|
||||
|
||||
|
|
|
@ -1462,8 +1462,7 @@ enum server_fd_type
|
|||
/* Perform a send on a socket */
|
||||
@REQ(send_socket)
|
||||
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 */
|
||||
|
|
|
@ -1051,8 +1051,7 @@ C_ASSERT( FIELD_OFFSET(struct recv_socket_reply, options) == 12 );
|
|||
C_ASSERT( FIELD_OFFSET(struct recv_socket_reply, nonblocking) == 16 );
|
||||
C_ASSERT( sizeof(struct recv_socket_reply) == 24 );
|
||||
C_ASSERT( FIELD_OFFSET(struct send_socket_request, async) == 16 );
|
||||
C_ASSERT( FIELD_OFFSET(struct send_socket_request, status) == 56 );
|
||||
C_ASSERT( FIELD_OFFSET(struct send_socket_request, total) == 60 );
|
||||
C_ASSERT( FIELD_OFFSET(struct send_socket_request, force_async) == 56 );
|
||||
C_ASSERT( sizeof(struct send_socket_request) == 64 );
|
||||
C_ASSERT( FIELD_OFFSET(struct send_socket_reply, wait) == 8 );
|
||||
C_ASSERT( FIELD_OFFSET(struct send_socket_reply, options) == 12 );
|
||||
|
|
|
@ -3508,10 +3508,11 @@ static void send_socket_completion_callback( void *private )
|
|||
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;
|
||||
int bind_errno = 0;
|
||||
|
||||
if (!sock) return;
|
||||
fd = sock->fd;
|
||||
|
@ -3520,7 +3521,6 @@ DECL_HANDLER(send_socket)
|
|||
{
|
||||
union unix_sockaddr unix_addr;
|
||||
socklen_t unix_len;
|
||||
int bind_errno = 0;
|
||||
int unix_fd = get_unix_fd( fd );
|
||||
|
||||
unix_len = get_unix_sockaddr_any( &unix_addr, sock->family );
|
||||
|
@ -3532,36 +3532,15 @@ DECL_HANDLER(send_socket)
|
|||
sock->addr_len = sockaddr_from_unix( &unix_addr, &sock->addr.addr, sizeof(sock->addr) );
|
||||
sock->bound = 1;
|
||||
}
|
||||
else if (status == STATUS_PENDING || status == STATUS_DEVICE_NOT_READY)
|
||||
status = sock_get_ntstatus( bind_errno ? bind_errno : errno );
|
||||
else if (!bind_errno) bind_errno = errno;
|
||||
}
|
||||
|
||||
/* 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 (bind_errno) status = sock_get_ntstatus( bind_errno );
|
||||
else 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
|
||||
|
@ -3580,6 +3559,9 @@ 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 )))
|
||||
{
|
||||
struct send_req *send_req;
|
||||
|
@ -3594,7 +3576,6 @@ DECL_HANDLER(send_socket)
|
|||
else if (status == STATUS_PENDING || status == STATUS_DEVICE_NOT_READY)
|
||||
status = STATUS_NO_MEMORY;
|
||||
|
||||
if (status == STATUS_SUCCESS) iosb->result = req->total;
|
||||
release_object( iosb );
|
||||
|
||||
set_error( status );
|
||||
|
|
|
@ -2045,8 +2045,7 @@ static void dump_recv_socket_reply( const struct recv_socket_reply *req )
|
|||
static void dump_send_socket_request( const struct send_socket_request *req )
|
||||
{
|
||||
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_send_socket_reply( const struct send_socket_reply *req )
|
||||
|
|
Loading…
Add table
Reference in a new issue