mirror of
https://gitlab.winehq.org/wine/wine.git
synced 2024-11-19 17:06:04 -07:00
ntdll: Don't cancel background socket sends.
This commit is contained in:
parent
d9a123b6cf
commit
3d1c2b0ede
Notes:
Alexandre Julliard
2024-09-18 23:20:34 +02:00
Approved-by: Elizabeth Figura (@zfigura) Approved-by: Alexandre Julliard (@julliard) Merge-Request: https://gitlab.winehq.org/wine/wine/merge_requests/6490
10 changed files with 52 additions and 33 deletions
|
@ -1105,7 +1105,7 @@ static void sock_save_icmp_id( struct async_send_ioctl *async )
|
||||||
}
|
}
|
||||||
|
|
||||||
static NTSTATUS sock_send( HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc, void *apc_user,
|
static NTSTATUS sock_send( HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc, void *apc_user,
|
||||||
IO_STATUS_BLOCK *io, int fd, struct async_send_ioctl *async, int force_async )
|
IO_STATUS_BLOCK *io, int fd, struct async_send_ioctl *async, unsigned int server_flags )
|
||||||
{
|
{
|
||||||
HANDLE wait_handle;
|
HANDLE wait_handle;
|
||||||
BOOL nonblocking;
|
BOOL nonblocking;
|
||||||
|
@ -1114,7 +1114,7 @@ static NTSTATUS sock_send( HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc, voi
|
||||||
|
|
||||||
SERVER_START_REQ( send_socket )
|
SERVER_START_REQ( send_socket )
|
||||||
{
|
{
|
||||||
req->force_async = force_async;
|
req->flags = server_flags;
|
||||||
req->async = server_async( handle, &async->io, event, apc, apc_user, iosb_client_ptr(io) );
|
req->async = server_async( handle, &async->io, event, apc, apc_user, iosb_client_ptr(io) );
|
||||||
status = wine_server_call( req );
|
status = wine_server_call( req );
|
||||||
wait_handle = wine_server_ptr_handle( reply->wait );
|
wait_handle = wine_server_ptr_handle( reply->wait );
|
||||||
|
@ -1132,7 +1132,7 @@ static NTSTATUS sock_send( HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc, voi
|
||||||
if (status == STATUS_ALERTED)
|
if (status == STATUS_ALERTED)
|
||||||
{
|
{
|
||||||
status = try_send( fd, async );
|
status = try_send( fd, async );
|
||||||
if (status == STATUS_DEVICE_NOT_READY && (force_async || !nonblocking))
|
if (status == STATUS_DEVICE_NOT_READY && ((server_flags & SERVER_SOCKET_IO_FORCE_ASYNC) || !nonblocking))
|
||||||
status = STATUS_PENDING;
|
status = STATUS_PENDING;
|
||||||
|
|
||||||
/* If we had a short write and the socket is nonblocking (and we are
|
/* If we had a short write and the socket is nonblocking (and we are
|
||||||
|
@ -1186,7 +1186,8 @@ static NTSTATUS sock_send( HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc, voi
|
||||||
p += sizeof(IO_STATUS_BLOCK);
|
p += sizeof(IO_STATUS_BLOCK);
|
||||||
rem_io->Pointer = p;
|
rem_io->Pointer = p;
|
||||||
p += sizeof(IO_STATUS_BLOCK32);
|
p += sizeof(IO_STATUS_BLOCK32);
|
||||||
status = sock_send( handle, NULL, NULL, NULL, rem_io, fd, rem_async, TRUE );
|
status = sock_send( handle, NULL, NULL, NULL, rem_io, fd, rem_async,
|
||||||
|
SERVER_SOCKET_IO_FORCE_ASYNC | SERVER_SOCKET_IO_SYSTEM );
|
||||||
if (status == STATUS_PENDING) status = STATUS_SUCCESS;
|
if (status == STATUS_PENDING) status = STATUS_SUCCESS;
|
||||||
if (!status)
|
if (!status)
|
||||||
{
|
{
|
||||||
|
@ -1251,7 +1252,7 @@ static NTSTATUS sock_ioctl_send( HANDLE handle, HANDLE event, PIO_APC_ROUTINE ap
|
||||||
async->iov_cursor = 0;
|
async->iov_cursor = 0;
|
||||||
async->sent_len = 0;
|
async->sent_len = 0;
|
||||||
|
|
||||||
return sock_send( handle, event, apc, apc_user, io, fd, async, force_async );
|
return sock_send( handle, event, apc, apc_user, io, fd, async, force_async ? SERVER_SOCKET_IO_FORCE_ASYNC : 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1274,7 +1275,7 @@ NTSTATUS sock_write( HANDLE handle, int fd, HANDLE event, PIO_APC_ROUTINE apc,
|
||||||
async->iov_cursor = 0;
|
async->iov_cursor = 0;
|
||||||
async->sent_len = 0;
|
async->sent_len = 0;
|
||||||
|
|
||||||
return sock_send( handle, event, apc, apc_user, io, fd, async, 1 );
|
return sock_send( handle, event, apc, apc_user, io, fd, async, SERVER_SOCKET_IO_FORCE_ASYNC );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1438,7 +1439,7 @@ static NTSTATUS sock_transmit( HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc,
|
||||||
|
|
||||||
SERVER_START_REQ( send_socket )
|
SERVER_START_REQ( send_socket )
|
||||||
{
|
{
|
||||||
req->force_async = 1;
|
req->flags = SERVER_SOCKET_IO_FORCE_ASYNC;
|
||||||
req->async = server_async( handle, &async->io, event, apc, apc_user, iosb_client_ptr(io) );
|
req->async = server_async( handle, &async->io, event, apc, apc_user, iosb_client_ptr(io) );
|
||||||
status = wine_server_call( req );
|
status = wine_server_call( req );
|
||||||
wait_handle = wine_server_ptr_handle( reply->wait );
|
wait_handle = wine_server_ptr_handle( reply->wait );
|
||||||
|
|
|
@ -14369,7 +14369,7 @@ static void test_send_buffering(void)
|
||||||
ok(recv_size <= d.sent_size, "got ret %d, recv_size %d, sent_size %d.\n", ret, recv_size, d.sent_size);
|
ok(recv_size <= d.sent_size, "got ret %d, recv_size %d, sent_size %d.\n", ret, recv_size, d.sent_size);
|
||||||
}
|
}
|
||||||
ok(!ret && !WSAGetLastError(), "got ret %d, error %u.\n", ret, WSAGetLastError());
|
ok(!ret && !WSAGetLastError(), "got ret %d, error %u.\n", ret, WSAGetLastError());
|
||||||
todo_wine ok(recv_size == d.sent_size, "got %d, expected %d.\n", recv_size, d.sent_size);
|
ok(recv_size == d.sent_size, "got %d, expected %d.\n", recv_size, d.sent_size);
|
||||||
closesocket(client);
|
closesocket(client);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1898,10 +1898,8 @@ struct recv_socket_reply
|
||||||
struct send_socket_request
|
struct send_socket_request
|
||||||
{
|
{
|
||||||
struct request_header __header;
|
struct request_header __header;
|
||||||
char __pad_12[4];
|
unsigned int flags;
|
||||||
async_data_t async;
|
async_data_t async;
|
||||||
int force_async;
|
|
||||||
char __pad_60[4];
|
|
||||||
};
|
};
|
||||||
struct send_socket_reply
|
struct send_socket_reply
|
||||||
{
|
{
|
||||||
|
@ -1912,6 +1910,8 @@ struct send_socket_reply
|
||||||
char __pad_20[4];
|
char __pad_20[4];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define SERVER_SOCKET_IO_FORCE_ASYNC 0x01
|
||||||
|
#define SERVER_SOCKET_IO_SYSTEM 0x02
|
||||||
|
|
||||||
|
|
||||||
struct socket_get_events_request
|
struct socket_get_events_request
|
||||||
|
@ -6693,7 +6693,7 @@ union generic_reply
|
||||||
|
|
||||||
/* ### protocol_version begin ### */
|
/* ### protocol_version begin ### */
|
||||||
|
|
||||||
#define SERVER_PROTOCOL_VERSION 840
|
#define SERVER_PROTOCOL_VERSION 841
|
||||||
|
|
||||||
/* ### protocol_version end ### */
|
/* ### protocol_version end ### */
|
||||||
|
|
||||||
|
|
|
@ -57,6 +57,7 @@ struct async
|
||||||
unsigned int canceled :1; /* have we already queued cancellation for this async? */
|
unsigned int canceled :1; /* have we already queued cancellation for this async? */
|
||||||
unsigned int unknown_status :1; /* initial status is not known yet */
|
unsigned int unknown_status :1; /* initial status is not known yet */
|
||||||
unsigned int blocking :1; /* async is blocking */
|
unsigned int blocking :1; /* async is blocking */
|
||||||
|
unsigned int is_system :1; /* background system operation not affecting userspace visible state. */
|
||||||
struct completion *completion; /* completion associated with fd */
|
struct completion *completion; /* completion associated with fd */
|
||||||
apc_param_t comp_key; /* completion key associated with fd */
|
apc_param_t comp_key; /* completion key associated with fd */
|
||||||
unsigned int comp_flags; /* completion flags */
|
unsigned int comp_flags; /* completion flags */
|
||||||
|
@ -243,7 +244,7 @@ void queue_async( struct async_queue *queue, struct async *async )
|
||||||
grab_object( async );
|
grab_object( async );
|
||||||
list_add_tail( &queue->queue, &async->queue_entry );
|
list_add_tail( &queue->queue, &async->queue_entry );
|
||||||
|
|
||||||
set_fd_signaled( async->fd, 0 );
|
if (!async->is_system) set_fd_signaled( async->fd, 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* create an async on a given queue of a fd */
|
/* create an async on a given queue of a fd */
|
||||||
|
@ -277,6 +278,7 @@ struct async *create_async( struct fd *fd, struct thread *thread, const async_da
|
||||||
async->canceled = 0;
|
async->canceled = 0;
|
||||||
async->unknown_status = 0;
|
async->unknown_status = 0;
|
||||||
async->blocking = !is_fd_overlapped( fd );
|
async->blocking = !is_fd_overlapped( fd );
|
||||||
|
async->is_system = 0;
|
||||||
async->completion = fd_get_completion( fd, &async->comp_key );
|
async->completion = fd_get_completion( fd, &async->comp_key );
|
||||||
async->comp_flags = 0;
|
async->comp_flags = 0;
|
||||||
async->completion_callback = NULL;
|
async->completion_callback = NULL;
|
||||||
|
@ -529,7 +531,7 @@ void async_set_result( struct object *obj, unsigned int status, apc_param_t tota
|
||||||
}
|
}
|
||||||
|
|
||||||
if (async->event) set_event( async->event );
|
if (async->event) set_event( async->event );
|
||||||
else if (async->fd) set_fd_signaled( async->fd, 1 );
|
else if (async->fd && !async->is_system) set_fd_signaled( async->fd, 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!async->signaled)
|
if (!async->signaled)
|
||||||
|
@ -584,7 +586,7 @@ static int cancel_async( struct process *process, struct object *obj, struct thr
|
||||||
restart:
|
restart:
|
||||||
LIST_FOR_EACH_ENTRY( async, &process->asyncs, struct async, process_entry )
|
LIST_FOR_EACH_ENTRY( async, &process->asyncs, struct async, process_entry )
|
||||||
{
|
{
|
||||||
if (async->terminated || async->canceled) continue;
|
if (async->terminated || async->canceled || async->is_system) continue;
|
||||||
if ((!obj || (get_fd_user( async->fd ) == obj)) &&
|
if ((!obj || (get_fd_user( async->fd ) == obj)) &&
|
||||||
(!thread || async->thread == thread) &&
|
(!thread || async->thread == thread) &&
|
||||||
(!iosb || async->data.iosb == iosb))
|
(!iosb || async->data.iosb == iosb))
|
||||||
|
@ -621,7 +623,16 @@ restart:
|
||||||
|
|
||||||
void cancel_process_asyncs( struct process *process )
|
void cancel_process_asyncs( struct process *process )
|
||||||
{
|
{
|
||||||
cancel_async( process, NULL, NULL, 0 );
|
struct async *async;
|
||||||
|
|
||||||
|
restart:
|
||||||
|
LIST_FOR_EACH_ENTRY( async, &process->asyncs, struct async, process_entry )
|
||||||
|
{
|
||||||
|
if (async->terminated || async->canceled) continue;
|
||||||
|
async->canceled = 1;
|
||||||
|
fd_cancel_async( async->fd, async );
|
||||||
|
goto restart;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int async_close_obj_handle( struct object *obj, struct process *process, obj_handle_t handle )
|
int async_close_obj_handle( struct object *obj, struct process *process, obj_handle_t handle )
|
||||||
|
@ -655,6 +666,7 @@ restart:
|
||||||
{
|
{
|
||||||
if (async->thread != thread || async->terminated || async->canceled) continue;
|
if (async->thread != thread || async->terminated || async->canceled) continue;
|
||||||
if (async->completion && async->data.apc_context && !async->event) continue;
|
if (async->completion && async->data.apc_context && !async->event) continue;
|
||||||
|
if (async->is_system) continue;
|
||||||
|
|
||||||
async->canceled = 1;
|
async->canceled = 1;
|
||||||
fd_cancel_async( async->fd, async );
|
fd_cancel_async( async->fd, async );
|
||||||
|
@ -741,7 +753,7 @@ static struct iosb *create_iosb( const void *in_data, data_size_t in_size, data_
|
||||||
|
|
||||||
/* create an async associated with iosb for async-based requests
|
/* create an async associated with iosb for async-based requests
|
||||||
* returned async must be passed to async_handoff */
|
* returned async must be passed to async_handoff */
|
||||||
struct async *create_request_async( struct fd *fd, unsigned int comp_flags, const async_data_t *data )
|
struct async *create_request_async( struct fd *fd, unsigned int comp_flags, const async_data_t *data, int is_system )
|
||||||
{
|
{
|
||||||
struct async *async;
|
struct async *async;
|
||||||
struct iosb *iosb;
|
struct iosb *iosb;
|
||||||
|
@ -760,6 +772,7 @@ struct async *create_request_async( struct fd *fd, unsigned int comp_flags, cons
|
||||||
}
|
}
|
||||||
async->pending = 0;
|
async->pending = 0;
|
||||||
async->direct_result = 1;
|
async->direct_result = 1;
|
||||||
|
async->is_system = !!is_system;
|
||||||
async->comp_flags = comp_flags;
|
async->comp_flags = comp_flags;
|
||||||
}
|
}
|
||||||
return async;
|
return async;
|
||||||
|
|
10
server/fd.c
10
server/fd.c
|
@ -2719,7 +2719,7 @@ DECL_HANDLER(flush)
|
||||||
|
|
||||||
if (!fd) return;
|
if (!fd) return;
|
||||||
|
|
||||||
if ((async = create_request_async( fd, fd->comp_flags, &req->async )))
|
if ((async = create_request_async( fd, fd->comp_flags, &req->async, 0 )))
|
||||||
{
|
{
|
||||||
fd->fd_ops->flush( fd, async );
|
fd->fd_ops->flush( fd, async );
|
||||||
reply->event = async_handoff( async, NULL, 1 );
|
reply->event = async_handoff( async, NULL, 1 );
|
||||||
|
@ -2748,7 +2748,7 @@ DECL_HANDLER(get_volume_info)
|
||||||
|
|
||||||
if (!fd) return;
|
if (!fd) return;
|
||||||
|
|
||||||
if ((async = create_request_async( fd, fd->comp_flags, &req->async )))
|
if ((async = create_request_async( fd, fd->comp_flags, &req->async, 0 )))
|
||||||
{
|
{
|
||||||
fd->fd_ops->get_volume_info( fd, async, req->info_class );
|
fd->fd_ops->get_volume_info( fd, async, req->info_class );
|
||||||
reply->wait = async_handoff( async, NULL, 1 );
|
reply->wait = async_handoff( async, NULL, 1 );
|
||||||
|
@ -2824,7 +2824,7 @@ DECL_HANDLER(read)
|
||||||
|
|
||||||
if (!fd) return;
|
if (!fd) return;
|
||||||
|
|
||||||
if ((async = create_request_async( fd, fd->comp_flags, &req->async )))
|
if ((async = create_request_async( fd, fd->comp_flags, &req->async, 0 )))
|
||||||
{
|
{
|
||||||
fd->fd_ops->read( fd, async, req->pos );
|
fd->fd_ops->read( fd, async, req->pos );
|
||||||
reply->wait = async_handoff( async, NULL, 0 );
|
reply->wait = async_handoff( async, NULL, 0 );
|
||||||
|
@ -2842,7 +2842,7 @@ DECL_HANDLER(write)
|
||||||
|
|
||||||
if (!fd) return;
|
if (!fd) return;
|
||||||
|
|
||||||
if ((async = create_request_async( fd, fd->comp_flags, &req->async )))
|
if ((async = create_request_async( fd, fd->comp_flags, &req->async, 0 )))
|
||||||
{
|
{
|
||||||
fd->fd_ops->write( fd, async, req->pos );
|
fd->fd_ops->write( fd, async, req->pos );
|
||||||
reply->wait = async_handoff( async, &reply->size, 0 );
|
reply->wait = async_handoff( async, &reply->size, 0 );
|
||||||
|
@ -2861,7 +2861,7 @@ DECL_HANDLER(ioctl)
|
||||||
|
|
||||||
if (!fd) return;
|
if (!fd) return;
|
||||||
|
|
||||||
if ((async = create_request_async( fd, fd->comp_flags, &req->async )))
|
if ((async = create_request_async( fd, fd->comp_flags, &req->async, 0 )))
|
||||||
{
|
{
|
||||||
fd->fd_ops->ioctl( fd, req->code, async );
|
fd->fd_ops->ioctl( fd, req->code, async );
|
||||||
reply->wait = async_handoff( async, NULL, 0 );
|
reply->wait = async_handoff( async, NULL, 0 );
|
||||||
|
|
|
@ -250,7 +250,8 @@ typedef void (*async_completion_callback)( void *private );
|
||||||
|
|
||||||
extern void free_async_queue( struct async_queue *queue );
|
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_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 struct async *create_request_async( struct fd *fd, unsigned int comp_flags, const async_data_t *data,
|
||||||
|
int is_system );
|
||||||
extern obj_handle_t async_handoff( struct async *async, 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 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_timeout( struct async *async, timeout_t timeout, unsigned int status );
|
||||||
|
|
|
@ -1577,14 +1577,16 @@ enum server_fd_type
|
||||||
|
|
||||||
/* Perform a send on a socket */
|
/* Perform a send on a socket */
|
||||||
@REQ(send_socket)
|
@REQ(send_socket)
|
||||||
|
unsigned int flags; /* SERVER_SOCKET_IO_* flags */
|
||||||
async_data_t async; /* async I/O parameters */
|
async_data_t async; /* async I/O parameters */
|
||||||
int force_async; /* Force asynchronous mode? */
|
|
||||||
@REPLY
|
@REPLY
|
||||||
obj_handle_t wait; /* handle to wait on for blocking send */
|
obj_handle_t wait; /* handle to wait on for blocking send */
|
||||||
unsigned int options; /* device open options */
|
unsigned int options; /* device open options */
|
||||||
int nonblocking; /* is socket non-blocking? */
|
int nonblocking; /* is socket non-blocking? */
|
||||||
@END
|
@END
|
||||||
|
|
||||||
|
#define SERVER_SOCKET_IO_FORCE_ASYNC 0x01
|
||||||
|
#define SERVER_SOCKET_IO_SYSTEM 0x02
|
||||||
|
|
||||||
/* Get socket event flags */
|
/* Get socket event flags */
|
||||||
@REQ(socket_get_events)
|
@REQ(socket_get_events)
|
||||||
|
|
|
@ -1098,9 +1098,9 @@ C_ASSERT( FIELD_OFFSET(struct recv_socket_reply, wait) == 8 );
|
||||||
C_ASSERT( FIELD_OFFSET(struct recv_socket_reply, options) == 12 );
|
C_ASSERT( FIELD_OFFSET(struct recv_socket_reply, options) == 12 );
|
||||||
C_ASSERT( FIELD_OFFSET(struct recv_socket_reply, nonblocking) == 16 );
|
C_ASSERT( FIELD_OFFSET(struct recv_socket_reply, nonblocking) == 16 );
|
||||||
C_ASSERT( sizeof(struct recv_socket_reply) == 24 );
|
C_ASSERT( sizeof(struct recv_socket_reply) == 24 );
|
||||||
|
C_ASSERT( FIELD_OFFSET(struct send_socket_request, flags) == 12 );
|
||||||
C_ASSERT( FIELD_OFFSET(struct send_socket_request, async) == 16 );
|
C_ASSERT( FIELD_OFFSET(struct send_socket_request, async) == 16 );
|
||||||
C_ASSERT( FIELD_OFFSET(struct send_socket_request, force_async) == 56 );
|
C_ASSERT( sizeof(struct send_socket_request) == 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, wait) == 8 );
|
||||||
C_ASSERT( FIELD_OFFSET(struct send_socket_reply, options) == 12 );
|
C_ASSERT( FIELD_OFFSET(struct send_socket_reply, options) == 12 );
|
||||||
C_ASSERT( FIELD_OFFSET(struct send_socket_reply, nonblocking) == 16 );
|
C_ASSERT( FIELD_OFFSET(struct send_socket_reply, nonblocking) == 16 );
|
||||||
|
|
|
@ -3915,7 +3915,7 @@ DECL_HANDLER(recv_socket)
|
||||||
sock->pending_events &= ~(req->oob ? AFD_POLL_OOB : AFD_POLL_READ);
|
sock->pending_events &= ~(req->oob ? AFD_POLL_OOB : AFD_POLL_READ);
|
||||||
sock->reported_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 ((async = create_request_async( fd, get_fd_comp_flags( fd ), &req->async, 0 )))
|
||||||
{
|
{
|
||||||
set_error( status );
|
set_error( status );
|
||||||
|
|
||||||
|
@ -3963,6 +3963,7 @@ DECL_HANDLER(send_socket)
|
||||||
struct async *async;
|
struct async *async;
|
||||||
struct fd *fd;
|
struct fd *fd;
|
||||||
int bind_errno = 0;
|
int bind_errno = 0;
|
||||||
|
BOOL force_async = req->flags & SERVER_SOCKET_IO_FORCE_ASYNC;
|
||||||
|
|
||||||
if (!sock) return;
|
if (!sock) return;
|
||||||
fd = sock->fd;
|
fd = sock->fd;
|
||||||
|
@ -3985,7 +3986,7 @@ DECL_HANDLER(send_socket)
|
||||||
else if (!bind_errno) bind_errno = errno;
|
else if (!bind_errno) bind_errno = errno;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!req->force_async && !sock->nonblocking && is_fd_overlapped( fd ))
|
if (!force_async && !sock->nonblocking && is_fd_overlapped( fd ))
|
||||||
timeout = (timeout_t)sock->sndtimeo * -10000;
|
timeout = (timeout_t)sock->sndtimeo * -10000;
|
||||||
|
|
||||||
if (bind_errno) status = sock_get_ntstatus( bind_errno );
|
if (bind_errno) status = sock_get_ntstatus( bind_errno );
|
||||||
|
@ -3996,7 +3997,7 @@ DECL_HANDLER(send_socket)
|
||||||
* asyncs will not consume all available space; if there's no space
|
* asyncs will not consume all available space; if there's no space
|
||||||
* available, the current request won't be immediately satiable.
|
* available, the current request won't be immediately satiable.
|
||||||
*/
|
*/
|
||||||
if ((!req->force_async && sock->nonblocking) || check_fd_events( sock->fd, POLLOUT ))
|
if ((!force_async && sock->nonblocking) || check_fd_events( sock->fd, POLLOUT ))
|
||||||
{
|
{
|
||||||
/* Give the client opportunity to complete synchronously.
|
/* Give the client opportunity to complete synchronously.
|
||||||
* If it turns out that the I/O request is not actually immediately satiable,
|
* If it turns out that the I/O request is not actually immediately satiable,
|
||||||
|
@ -4021,10 +4022,11 @@ DECL_HANDLER(send_socket)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (status == STATUS_PENDING && !req->force_async && sock->nonblocking)
|
if (status == STATUS_PENDING && !force_async && sock->nonblocking)
|
||||||
status = STATUS_DEVICE_NOT_READY;
|
status = STATUS_DEVICE_NOT_READY;
|
||||||
|
|
||||||
if ((async = create_request_async( fd, get_fd_comp_flags( fd ), &req->async )))
|
if ((async = create_request_async( fd, get_fd_comp_flags( fd ), &req->async,
|
||||||
|
req->flags & SERVER_SOCKET_IO_SYSTEM )))
|
||||||
{
|
{
|
||||||
struct send_req *send_req;
|
struct send_req *send_req;
|
||||||
struct iosb *iosb = async_get_iosb( async );
|
struct iosb *iosb = async_get_iosb( async );
|
||||||
|
|
|
@ -2209,8 +2209,8 @@ static void dump_recv_socket_reply( const struct recv_socket_reply *req )
|
||||||
|
|
||||||
static void dump_send_socket_request( const struct send_socket_request *req )
|
static void dump_send_socket_request( const struct send_socket_request *req )
|
||||||
{
|
{
|
||||||
dump_async_data( " async=", &req->async );
|
fprintf( stderr, " flags=%08x", req->flags );
|
||||||
fprintf( stderr, ", force_async=%d", req->force_async );
|
dump_async_data( ", async=", &req->async );
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dump_send_socket_reply( const struct send_socket_reply *req )
|
static void dump_send_socket_reply( const struct send_socket_reply *req )
|
||||||
|
|
Loading…
Reference in a new issue