Module: wine Branch: master Commit: 055918c9829d4b31e4599bf3a45faf501116a15e URL: http://source.winehq.org/git/wine.git/?a=commit;h=055918c9829d4b31e4599bf3a4...
Author: Jacek Caban jacek@codeweavers.com Date: Thu Dec 1 12:10:23 2016 +0100
server: Store async list in process object and use that to find async in cansel_async request.
Signed-off-by: Jacek Caban jacek@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
server/async.c | 40 +++++++++++++++++++++++++++++----------- server/fd.c | 21 +-------------------- server/file.h | 2 -- server/process.c | 2 ++ server/process.h | 1 + server/sock.c | 16 +--------------- 6 files changed, 34 insertions(+), 48 deletions(-)
diff --git a/server/async.c b/server/async.c index 64aa27a..5acd1e7 100644 --- a/server/async.c +++ b/server/async.c @@ -31,12 +31,15 @@ #include "object.h" #include "file.h" #include "request.h" +#include "process.h" +#include "handle.h"
struct async { struct object obj; /* object header */ struct thread *thread; /* owning thread */ struct list queue_entry; /* entry in async queue list */ + struct list process_entry; /* entry in process list */ struct async_queue *queue; /* queue containing this async */ unsigned int status; /* current status */ struct timeout_user *timeout; @@ -132,6 +135,7 @@ static void async_destroy( struct object *obj ) struct async *async = (struct async *)obj; assert( obj->ops == &async_ops );
+ list_remove( &async->process_entry ); list_remove( &async->queue_entry ); async_reselect( async );
@@ -244,6 +248,7 @@ struct async *create_async( struct thread *thread, struct async_queue *queue, co async->signaled = 0;
list_add_tail( &queue->queue, &async->queue_entry ); + list_add_tail( &thread->process->asyncs, &async->process_entry ); grab_object( async );
if (queue->fd) set_fd_signaled( queue->fd, 0 ); @@ -343,23 +348,22 @@ int async_waiting( struct async_queue *queue ) return async->status == STATUS_PENDING; }
-int async_wake_up_by( struct async_queue *queue, struct process *process, - struct thread *thread, client_ptr_t iosb, unsigned int status ) +static int cancel_async( struct process *process, struct object *obj, struct thread *thread, client_ptr_t iosb ) { - struct list *ptr, *next; + struct async *async; int woken = 0;
- if (!queue || (!process && !thread && !iosb)) return 0; - - LIST_FOR_EACH_SAFE( ptr, next, &queue->queue ) +restart: + LIST_FOR_EACH_ENTRY( async, &process->asyncs, struct async, process_entry ) { - struct async *async = LIST_ENTRY( ptr, struct async, queue_entry ); - if ( (!process || async->thread->process == process) && - (!thread || async->thread == thread) && - (!iosb || async->data.iosb == iosb) ) + if (async->status == STATUS_CANCELLED) continue; + if ((!obj || (async->queue->fd && get_fd_user( async->queue->fd ) == obj)) && + (!thread || async->thread == thread) && + (!iosb || async->data.iosb == iosb)) { - async_terminate( async, status ); + async_terminate( async, STATUS_CANCELLED ); woken++; + goto restart; } } return woken; @@ -379,3 +383,17 @@ void async_wake_up( struct async_queue *queue, unsigned int status ) if (status == STATUS_ALERTED) break; /* only wake up the first one */ } } + +/* cancels all async I/O */ +DECL_HANDLER(cancel_async) +{ + struct object *obj = get_handle_obj( current->process, req->handle, 0, NULL ); + struct thread *thread = req->only_thread ? current : NULL; + + if (obj) + { + int count = cancel_async( current->process, obj, thread, req->iosb ); + if (!count && req->iosb) set_error( STATUS_NOT_FOUND ); + release_object( obj ); + } +} diff --git a/server/fd.c b/server/fd.c index 66d34d7..a75ff76 100644 --- a/server/fd.c +++ b/server/fd.c @@ -2118,12 +2118,7 @@ void default_fd_reselect_async( struct fd *fd, struct async_queue *queue ) /* default cancel_async() fd routine */ 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 ); - return n; + return 0; }
static inline int is_valid_mounted_device( struct stat *st ) @@ -2519,20 +2514,6 @@ DECL_HANDLER(register_async) } }
-/* cancels all async I/O */ -DECL_HANDLER(cancel_async) -{ - struct fd *fd = get_handle_fd_obj( current->process, req->handle, 0 ); - struct thread *thread = req->only_thread ? current : NULL; - - if (fd) - { - 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 ); - } -} - /* attach completion object to a fd */ DECL_HANDLER(set_completion_info) { diff --git a/server/file.h b/server/file.h index b643d94..7c68248 100644 --- a/server/file.h +++ b/server/file.h @@ -175,8 +175,6 @@ extern void async_set_result( struct object *obj, unsigned int status, extern int async_queued( struct async_queue *queue ); extern int async_waiting( struct async_queue *queue ); extern void async_terminate( struct async *async, unsigned int status ); -extern int async_wake_up_by( struct async_queue *queue, struct process *process, - struct thread *thread, client_ptr_t iosb, unsigned int status ); extern void async_wake_up( struct async_queue *queue, unsigned int status ); extern struct completion *fd_get_completion( struct fd *fd, apc_param_t *p_key ); extern void fd_copy_completion( struct fd *src, struct fd *dst ); diff --git a/server/process.c b/server/process.c index 528ec74..cca18e9 100644 --- a/server/process.c +++ b/server/process.c @@ -535,6 +535,7 @@ struct thread *create_process( int fd, struct thread *parent_thread, int inherit process->rawinput_kbd = NULL; list_init( &process->thread_list ); list_init( &process->locks ); + list_init( &process->asyncs ); list_init( &process->classes ); list_init( &process->dlls ); list_init( &process->rawinput_devices ); @@ -614,6 +615,7 @@ static void process_destroy( struct object *obj )
/* we can't have a thread remaining */ assert( list_empty( &process->thread_list )); + assert( list_empty( &process->asyncs ));
assert( !process->sigkill_timeout ); /* timeout should hold a reference to the process */
diff --git a/server/process.h b/server/process.h index 4e6de69..548796f 100644 --- a/server/process.h +++ b/server/process.h @@ -78,6 +78,7 @@ struct process unsigned int is_terminating:1;/* is process terminating? */ struct job *job; /* job object ascoicated with this process */ struct list job_entry; /* list entry for job object */ + struct list asyncs; /* list of async object owned by the process */ struct list locks; /* list of file locks owned by the process */ struct list classes; /* window classes owned by the process */ struct console_input*console; /* console input */ diff --git a/server/sock.c b/server/sock.c index 0de6f68..2cd3b0e 100644 --- a/server/sock.c +++ b/server/sock.c @@ -132,7 +132,6 @@ 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 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 ); @@ -171,7 +170,7 @@ static const struct fd_ops sock_fd_ops = sock_ioctl, /* ioctl */ sock_queue_async, /* queue_async */ sock_reselect_async, /* reselect_async */ - sock_cancel_async /* cancel_async */ + default_fd_cancel_async /* cancel_async */ };
@@ -611,19 +610,6 @@ static void sock_reselect_async( struct fd *fd, struct async_queue *queue ) sock_reselect( sock ); }
-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 ); - n += async_wake_up_by( sock->ifchange_q, process, thread, iosb, STATUS_CANCELLED ); - return n; -} - static struct fd *sock_get_fd( struct object *obj ) { struct sock *sock = (struct sock *)obj;