Jacek Caban : server: Keep weak fd reference in async object when async is queued.

Alexandre Julliard julliard at winehq.org
Wed Jul 5 15:41:01 CDT 2017


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

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Tue Jul  4 15:25:51 2017 +0200

server: Keep weak fd reference in async object when async is queued.

Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 server/async.c | 22 ++++++++++------------
 1 file changed, 10 insertions(+), 12 deletions(-)

diff --git a/server/async.c b/server/async.c
index 3a83a63..ed85899 100644
--- a/server/async.c
+++ b/server/async.c
@@ -118,7 +118,7 @@ static const struct object_ops async_queue_ops =
 
 static inline void async_reselect( struct async *async )
 {
-    if (async->queue && async->queue->fd) fd_reselect_async( async->queue->fd, async->queue );
+    if (async->queue && async->fd) fd_reselect_async( async->fd, async->queue );
 }
 
 static void async_dump( struct object *obj, int verbose )
@@ -167,8 +167,8 @@ static void async_destroy( struct object *obj )
         async_reselect( async );
         release_object( async->queue );
     }
+    else if (async->fd) release_object( async->fd );
 
-    if (async->fd) release_object( async->fd );
     if (async->timeout) remove_timeout_user( async->timeout );
     if (async->event) release_object( async->event );
     if (async->iosb) release_object( async->iosb );
@@ -250,8 +250,11 @@ struct async_queue *create_async_queue( struct fd *fd )
 /* free an async queue, cancelling all async operations */
 void free_async_queue( struct async_queue *queue )
 {
+    struct async *async;
+
     if (!queue) return;
     if (queue->fd) queue->completion = fd_get_completion( queue->fd, &queue->comp_key );
+    LIST_FOR_EACH_ENTRY( async, &queue->queue, struct async, queue_entry ) async->fd = NULL;
     queue->fd = NULL;
     async_wake_up( queue, STATUS_HANDLES_CLOSED );
     release_object( queue );
@@ -259,14 +262,14 @@ void free_async_queue( struct async_queue *queue )
 
 void queue_async( struct async_queue *queue, struct async *async )
 {
+    /* fd will be set to NULL in free_async_queue when fd is destroyed */
     release_object( async->fd );
-    async->fd = NULL;
 
     async->queue = (struct async_queue *)grab_object( queue );
     grab_object( async );
     list_add_tail( &queue->queue, &async->queue_entry );
 
-    if (queue->fd) set_fd_signaled( queue->fd, 0 );
+    if (async->fd) set_fd_signaled( async->fd, 0 );
 }
 
 /* create an async on a given queue of a fd */
@@ -383,12 +386,10 @@ void async_set_timeout( struct async *async, timeout_t timeout, unsigned int sta
 static void add_async_completion( struct async *async, apc_param_t cvalue, unsigned int status,
                                   apc_param_t information )
 {
-    struct fd *fd = async->queue ? async->queue->fd : async->fd;
-
-    if (fd)
+    if (async->fd)
     {
         apc_param_t ckey;
-        struct completion *completion = fd_get_completion( fd, &ckey );
+        struct completion *completion = fd_get_completion( async->fd, &ckey );
 
         if (completion)
         {
@@ -443,7 +444,6 @@ void async_set_result( struct object *obj, unsigned int status, apc_param_t tota
 
         if (async->event) set_event( async->event );
         else if (async->fd) set_fd_signaled( async->fd, 1 );
-        else if (async->queue && async->queue->fd) set_fd_signaled( async->queue->fd, 1 );
         if (!async->signaled)
         {
             async->signaled = 1;
@@ -473,15 +473,13 @@ int async_waiting( struct async_queue *queue )
 static int cancel_async( struct process *process, struct object *obj, struct thread *thread, client_ptr_t iosb )
 {
     struct async *async;
-    struct fd *fd;
     int woken = 0;
 
 restart:
     LIST_FOR_EACH_ENTRY( async, &process->asyncs, struct async, process_entry )
     {
         if (async->status == STATUS_CANCELLED) continue;
-        fd = async->queue ? async->queue->fd : async->fd;
-        if ((!obj || (fd && get_fd_user( fd ) == obj)) &&
+        if ((!obj || (async->fd && get_fd_user( async->fd ) == obj)) &&
             (!thread || async->thread == thread) &&
             (!iosb || async->data.iosb == iosb))
         {




More information about the wine-cvs mailing list