Jacek Caban : server: Store async list in process object and use that to find async in cansel_async request.

Alexandre Julliard julliard at winehq.org
Thu Dec 1 15:37:44 CST 2016


Module: wine
Branch: master
Commit: 055918c9829d4b31e4599bf3a45faf501116a15e
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=055918c9829d4b31e4599bf3a45faf501116a15e

Author: Jacek Caban <jacek at 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 at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at 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;




More information about the wine-cvs mailing list