From 83e3a9c9ba6efa583a0d7b641409c9a457fa8bfe Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Wed, 6 May 2015 13:48:05 +0900 Subject: [PATCH] server: Allow cancelling async I/O for all object types. --- server/fd.c | 8 ++++---- server/file.h | 4 ++-- server/sock.c | 9 +++++---- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/server/fd.c b/server/fd.c index e7f151af9ef..1253b3d2bdf 100644 --- a/server/fd.c +++ b/server/fd.c @@ -2100,15 +2100,14 @@ void default_fd_reselect_async( struct fd *fd, struct async_queue *queue ) } /* default cancel_async() fd routine */ -void default_fd_cancel_async( struct fd *fd, struct process *process, struct thread *thread, client_ptr_t iosb ) +int default_fd_cancel_async( struct fd *fd, struct process *process, struct thread *thread, client_ptr_t iosb ) { int n = 0; n += async_wake_up_by( fd->read_q, process, thread, iosb, STATUS_CANCELLED ); n += async_wake_up_by( fd->write_q, process, thread, iosb, STATUS_CANCELLED ); n += async_wake_up_by( fd->wait_q, process, thread, iosb, STATUS_CANCELLED ); - if (!n && iosb) - set_error( STATUS_NOT_FOUND ); + return n; } static inline int is_valid_mounted_device( struct stat *st ) @@ -2377,7 +2376,8 @@ DECL_HANDLER(cancel_async) if (fd) { - if (get_unix_fd( fd ) != -1) fd->fd_ops->cancel_async( fd, current->process, thread, req->iosb ); + int count = fd->fd_ops->cancel_async( fd, current->process, thread, req->iosb ); + if (!count && req->iosb) set_error( STATUS_NOT_FOUND ); release_object( fd ); } } diff --git a/server/file.h b/server/file.h index 7e8b12e4578..603b6868a2d 100644 --- a/server/file.h +++ b/server/file.h @@ -52,7 +52,7 @@ struct fd_ops /* selected events for async i/o need an update */ void (*reselect_async)( struct fd *, struct async_queue *queue ); /* cancel an async operation */ - void (*cancel_async)(struct fd *, struct process *process, struct thread *thread, client_ptr_t iosb); + int (*cancel_async)(struct fd *, struct process *process, struct thread *thread, client_ptr_t iosb); }; /* file descriptor functions */ @@ -98,7 +98,7 @@ extern obj_handle_t default_fd_ioctl( struct fd *fd, ioctl_code_t code, const as extern void no_fd_queue_async( struct fd *fd, const async_data_t *data, int type, int count ); extern void default_fd_queue_async( struct fd *fd, const async_data_t *data, int type, int count ); extern void default_fd_reselect_async( struct fd *fd, struct async_queue *queue ); -extern void default_fd_cancel_async( struct fd *fd, struct process *process, struct thread *thread, client_ptr_t iosb ); +extern int default_fd_cancel_async( struct fd *fd, struct process *process, struct thread *thread, client_ptr_t iosb ); extern void main_loop(void); extern void remove_process_locks( struct process *process ); diff --git a/server/sock.c b/server/sock.c index 337006f7d9d..c4dcf6fa782 100644 --- a/server/sock.c +++ b/server/sock.c @@ -133,7 +133,7 @@ static enum server_fd_type sock_get_fd_type( struct fd *fd ); static obj_handle_t sock_ioctl( struct fd *fd, ioctl_code_t code, const async_data_t *async, int blocking ); static void sock_queue_async( struct fd *fd, const async_data_t *data, int type, int count ); static void sock_reselect_async( struct fd *fd, struct async_queue *queue ); -static void sock_cancel_async( struct fd *fd, struct process *process, struct thread *thread, client_ptr_t iosb ); +static int sock_cancel_async( struct fd *fd, struct process *process, struct thread *thread, client_ptr_t iosb ); static int sock_get_ntstatus( int err ); static int sock_get_error( int err ); @@ -609,16 +609,17 @@ static void sock_reselect_async( struct fd *fd, struct async_queue *queue ) sock_reselect( sock ); } -static void sock_cancel_async( struct fd *fd, struct process *process, struct thread *thread, client_ptr_t iosb ) +static int sock_cancel_async( struct fd *fd, struct process *process, struct thread *thread, client_ptr_t iosb ) { struct sock *sock = get_fd_user( fd ); int n = 0; + assert( sock->obj.ops == &sock_ops ); n += async_wake_up_by( sock->read_q, process, thread, iosb, STATUS_CANCELLED ); n += async_wake_up_by( sock->write_q, process, thread, iosb, STATUS_CANCELLED ); - if (!n && iosb) - set_error( STATUS_NOT_FOUND ); + n += async_wake_up_by( sock->ifchange_q, process, thread, iosb, STATUS_CANCELLED ); + return n; } static struct fd *sock_get_fd( struct object *obj )