From: Jacek Caban Subject: [PATCH 03/16] server: Store associated async queue list in fd struct. Message-Id: <705a1a21-7504-a754-37fc-3f2500ea240b@codeweavers.com> Date: Wed, 5 Oct 2016 21:27:32 +0200 Signed-off-by: Jacek Caban --- This is needed for patch 8 to avoid adding new entry to fd_ops. Instead, I removed one entry in patch 5. server/async.c | 17 +++++++++++++++-- server/fd.c | 13 ++++++++++--- server/file.h | 2 ++ 3 files changed, 27 insertions(+), 5 deletions(-) diff --git a/server/async.c b/server/async.c index 64aa27a..a707c32 100644 --- a/server/async.c +++ b/server/async.c @@ -80,6 +80,7 @@ struct async_queue struct completion *completion; /* completion associated with a recently closed file descriptor */ apc_param_t comp_key; /* completion key associated with a recently closed file descriptor */ struct list queue; /* queue of async objects */ + struct list fd_entry; /* entry in fd queue list */ }; static void async_queue_dump( struct object *obj, int verbose ); @@ -204,6 +205,7 @@ struct async_queue *create_async_queue( struct fd *fd ) if (queue) { queue->fd = fd; + if (fd) fd_add_async_queue( fd, &queue->fd_entry ); queue->completion = NULL; list_init( &queue->queue ); } @@ -214,12 +216,23 @@ struct async_queue *create_async_queue( struct fd *fd ) void free_async_queue( struct async_queue *queue ) { if (!queue) return; - if (queue->fd) queue->completion = fd_get_completion( queue->fd, &queue->comp_key ); - queue->fd = NULL; + if (queue->fd) + { + queue->completion = fd_get_completion( queue->fd, &queue->comp_key ); + list_remove( &queue->fd_entry ); + queue->fd = NULL; + } async_wake_up( queue, STATUS_HANDLES_CLOSED ); release_object( queue ); } +/* free an async queues, cancelling all async operations */ +void free_async_queues( struct list *queues ) +{ + while (!list_empty( queues )) + free_async_queue( LIST_ENTRY( list_head(queues), struct async_queue, fd_entry )); +} + /* create an async on a given queue of a fd */ struct async *create_async( struct thread *thread, struct async_queue *queue, const async_data_t *data ) { diff --git a/server/fd.c b/server/fd.c index 17b1b66..09b8d65 100644 --- a/server/fd.c +++ b/server/fd.c @@ -192,6 +192,7 @@ struct fd struct async_queue *read_q; /* async readers of this fd */ struct async_queue *write_q; /* async writers of this fd */ struct async_queue *wait_q; /* other async waiters of this fd */ + struct list async_queues;/* list of async queues associated with this fd */ struct completion *completion; /* completion object attached to this fd */ apc_param_t comp_key; /* completion key to set in completion events */ }; @@ -1473,9 +1474,7 @@ static void fd_destroy( struct object *obj ) { struct fd *fd = (struct fd *)obj; - free_async_queue( fd->read_q ); - free_async_queue( fd->write_q ); - free_async_queue( fd->wait_q ); + free_async_queues( &fd->async_queues ); if (fd->completion) release_object( fd->completion ); remove_fd_locks( fd ); @@ -1609,6 +1608,7 @@ static struct fd *alloc_fd_object(void) fd->completion = NULL; list_init( &fd->inode_entry ); list_init( &fd->locks ); + list_init( &fd->async_queues ); if ((fd->poll_index = add_poll_user( fd )) == -1) { @@ -1645,6 +1645,7 @@ struct fd *alloc_pseudo_fd( const struct fd_ops *fd_user_ops, struct object *use fd->no_fd_status = STATUS_BAD_DEVICE_TYPE; list_init( &fd->inode_entry ); list_init( &fd->locks ); + list_init( &fd->async_queues ); return fd; } @@ -2126,6 +2127,12 @@ int default_fd_cancel_async( struct fd *fd, struct process *process, struct thre return n; } +/* add async queue to queue list */ +void fd_add_async_queue( struct fd *fd, struct list *queue_entry ) +{ + list_add_tail( &fd->async_queues, queue_entry ); +} + static inline int is_valid_mounted_device( struct stat *st ) { #if defined(linux) || defined(__sun__) diff --git a/server/file.h b/server/file.h index b643d94..fa08553 100644 --- a/server/file.h +++ b/server/file.h @@ -90,6 +90,7 @@ extern void default_poll_event( struct fd *fd, int event ); extern struct async *fd_queue_async( struct fd *fd, const async_data_t *data, int type ); extern void fd_async_wake_up( struct fd *fd, int type, unsigned int status ); extern void fd_reselect_async( struct fd *fd, struct async_queue *queue ); +extern void fd_add_async_queue( struct fd *fd, struct list *queue_entry ); extern obj_handle_t no_fd_read( struct fd *fd, const async_data_t *async, int blocking, file_pos_t pos ); extern obj_handle_t no_fd_write( struct fd *fd, const async_data_t *async, int blocking, file_pos_t pos, data_size_t *written ); @@ -167,6 +168,7 @@ extern struct object *create_serial( struct fd *fd ); /* async I/O functions */ extern struct async_queue *create_async_queue( struct fd *fd ); extern void free_async_queue( struct async_queue *queue ); +extern void free_async_queues( struct list *queues ); extern struct async *create_async( struct thread *thread, struct async_queue *queue, const async_data_t *data ); extern void async_set_timeout( struct async *async, timeout_t timeout, unsigned int status );