server: Use a callback to free the accept_req structure.
Signed-off-by: Zebediah Figura <z.figura12@gmail.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
12783dabbc
commit
61abc500f5
|
@ -55,6 +55,8 @@ struct async
|
|||
struct completion *completion; /* completion associated with fd */
|
||||
apc_param_t comp_key; /* completion key associated with fd */
|
||||
unsigned int comp_flags; /* completion flags */
|
||||
async_completion_callback completion_callback; /* callback to be called on completion */
|
||||
void *completion_callback_private; /* argument to completion_callback */
|
||||
};
|
||||
|
||||
static void async_dump( struct object *obj, int verbose );
|
||||
|
@ -247,6 +249,8 @@ struct async *create_async( struct fd *fd, struct thread *thread, const async_da
|
|||
async->direct_result = 0;
|
||||
async->completion = fd_get_completion( fd, &async->comp_key );
|
||||
async->comp_flags = 0;
|
||||
async->completion_callback = NULL;
|
||||
async->completion_callback_private = NULL;
|
||||
|
||||
if (iosb) async->iosb = (struct iosb *)grab_object( iosb );
|
||||
else async->iosb = NULL;
|
||||
|
@ -362,6 +366,13 @@ void async_set_timeout( struct async *async, timeout_t timeout, unsigned int sta
|
|||
async->timeout_status = status;
|
||||
}
|
||||
|
||||
/* set a callback to be notified when the async is completed */
|
||||
void async_set_completion_callback( struct async *async, async_completion_callback func, void *private )
|
||||
{
|
||||
async->completion_callback = func;
|
||||
async->completion_callback_private = private;
|
||||
}
|
||||
|
||||
static void add_async_completion( struct async *async, apc_param_t cvalue, unsigned int status,
|
||||
apc_param_t information )
|
||||
{
|
||||
|
@ -420,6 +431,10 @@ void async_set_result( struct object *obj, unsigned int status, apc_param_t tota
|
|||
async->signaled = 1;
|
||||
wake_up( &async->obj, 0 );
|
||||
}
|
||||
|
||||
if (async->completion_callback)
|
||||
async->completion_callback( async->completion_callback_private );
|
||||
async->completion_callback = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -212,6 +212,9 @@ extern int is_serial_fd( struct fd *fd );
|
|||
extern struct object *create_serial( struct fd *fd );
|
||||
|
||||
/* async I/O functions */
|
||||
|
||||
typedef void (*async_completion_callback)( void *private );
|
||||
|
||||
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_request_async( struct fd *fd, unsigned int comp_flags, const async_data_t *data );
|
||||
|
@ -219,6 +222,7 @@ extern obj_handle_t async_handoff( struct async *async, int success, data_size_t
|
|||
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_result( struct object *obj, unsigned int status, apc_param_t total );
|
||||
extern void async_set_completion_callback( struct async *async, async_completion_callback func, void *private );
|
||||
extern void set_async_pending( struct async *async, int signal );
|
||||
extern int async_waiting( struct async_queue *queue );
|
||||
extern void async_terminate( struct async *async, unsigned int status );
|
||||
|
|
|
@ -449,8 +449,9 @@ static inline int sock_error( struct fd *fd )
|
|||
return optval;
|
||||
}
|
||||
|
||||
static void free_accept_req( struct accept_req *req )
|
||||
static void free_accept_req( void *private )
|
||||
{
|
||||
struct accept_req *req = private;
|
||||
list_remove( &req->entry );
|
||||
if (req->acceptsock)
|
||||
{
|
||||
|
@ -582,7 +583,7 @@ static int sock_dispatch_asyncs( struct sock *sock, int event, int error )
|
|||
|
||||
LIST_FOR_EACH_ENTRY( req, &sock->accept_list, struct accept_req, entry )
|
||||
{
|
||||
if (!req->accepted)
|
||||
if (req->iosb->status == STATUS_PENDING && !req->accepted)
|
||||
{
|
||||
complete_async_accept( sock, req );
|
||||
if (get_error() != STATUS_PENDING)
|
||||
|
@ -591,7 +592,7 @@ static int sock_dispatch_asyncs( struct sock *sock, int event, int error )
|
|||
}
|
||||
}
|
||||
|
||||
if (sock->accept_recv_req)
|
||||
if (sock->accept_recv_req && sock->accept_recv_req->iosb->status == STATUS_PENDING)
|
||||
{
|
||||
complete_async_accept_recv( sock->accept_recv_req );
|
||||
if (get_error() != STATUS_PENDING)
|
||||
|
@ -626,9 +627,12 @@ static int sock_dispatch_asyncs( struct sock *sock, int event, int error )
|
|||
async_wake_up( &sock->write_q, status );
|
||||
|
||||
LIST_FOR_EACH_ENTRY_SAFE( req, next, &sock->accept_list, struct accept_req, entry )
|
||||
{
|
||||
if (req->iosb->status == STATUS_PENDING)
|
||||
async_terminate( req->async, status );
|
||||
}
|
||||
|
||||
if (sock->accept_recv_req)
|
||||
if (sock->accept_recv_req && sock->accept_recv_req->iosb->status == STATUS_PENDING)
|
||||
async_terminate( sock->accept_recv_req->async, status );
|
||||
}
|
||||
|
||||
|
@ -872,13 +876,6 @@ static void sock_queue_async( struct fd *fd, struct async *async, int type, int
|
|||
static void sock_reselect_async( struct fd *fd, struct async_queue *queue )
|
||||
{
|
||||
struct sock *sock = get_fd_user( fd );
|
||||
struct accept_req *req, *next;
|
||||
|
||||
LIST_FOR_EACH_ENTRY_SAFE( req, next, &sock->accept_list, struct accept_req, entry )
|
||||
{
|
||||
if (req->iosb->status != STATUS_PENDING)
|
||||
free_accept_req( req );
|
||||
}
|
||||
|
||||
/* ignore reselect on ifchange queue */
|
||||
if (&sock->ifchange_q != queue)
|
||||
|
@ -1434,6 +1431,7 @@ static int sock_ioctl( struct fd *fd, ioctl_code_t code, struct async *async )
|
|||
if (!(req = alloc_accept_req( sock, NULL, async, NULL ))) return 0;
|
||||
list_add_tail( &sock->accept_list, &req->entry );
|
||||
|
||||
async_set_completion_callback( async, free_accept_req, req );
|
||||
queue_async( &sock->accept_q, async );
|
||||
sock_reselect( sock );
|
||||
set_error( STATUS_PENDING );
|
||||
|
@ -1490,6 +1488,7 @@ static int sock_ioctl( struct fd *fd, ioctl_code_t code, struct async *async )
|
|||
release_object( acceptsock );
|
||||
|
||||
acceptsock->wparam = params->accept_handle;
|
||||
async_set_completion_callback( async, free_accept_req, req );
|
||||
queue_async( &sock->accept_q, async );
|
||||
sock_reselect( sock );
|
||||
set_error( STATUS_PENDING );
|
||||
|
|
Loading…
Reference in New Issue