[PATCH v2 1/3] server: Abort waiting on a completion port when closing it.

Alexey Prokhin alexey at prokhin.ru
Wed Apr 29 10:26:41 CDT 2020


Signed-off-by: Alexey Prokhin <alexey at prokhin.ru>
---
v2: Update kernelbase patch. Supersedes 184510
---
 server/completion.c | 25 ++++++++++++++++++++++---
 1 file changed, 22 insertions(+), 3 deletions(-)

diff --git a/server/completion.c b/server/completion.c
index db04727b93..9e15c1ca07 100644
--- a/server/completion.c
+++ b/server/completion.c
@@ -48,12 +48,14 @@ struct completion
     struct object  obj;
     struct list    queue;
     unsigned int   depth;
+    int            abandoned;
 };
 
 static void completion_dump( struct object*, int );
 static struct object_type *completion_get_type( struct object *obj );
 static int completion_signaled( struct object *obj, struct wait_queue_entry *entry );
 static unsigned int completion_map_access( struct object *obj, unsigned int access );
+static int completion_close( struct object *obj, struct process *process, obj_handle_t handle );
 static void completion_destroy( struct object * );
 
 static const struct object_ops completion_ops =
@@ -75,7 +77,7 @@ static const struct object_ops completion_ops =
     default_unlink_name,       /* unlink_name */
     no_open_file,              /* open_file */
     no_kernel_obj_list,        /* get_kernel_obj_list */
-    no_close_handle,           /* close_handle */
+    completion_close,          /* close_handle */
     completion_destroy         /* destroy */
 };
 
@@ -88,6 +90,22 @@ struct comp_msg
     unsigned int  status;
 };
 
+static int completion_close( struct object *obj, struct process *process, obj_handle_t handle )
+{
+    struct completion *completion = (struct completion *) obj;
+    struct wait_queue_entry *entry;
+
+    LIST_FOR_EACH_ENTRY( entry, &obj->wait_queue, struct wait_queue_entry, entry )
+    {
+        make_wait_abandoned( entry );
+    }
+
+    completion->abandoned = 1;
+    wake_up( &completion->obj, 0 );
+
+    return 1;
+}
+
 static void completion_destroy( struct object *obj)
 {
     struct completion *completion = (struct completion *) obj;
@@ -118,7 +136,7 @@ static int completion_signaled( struct object *obj, struct wait_queue_entry *ent
 {
     struct completion *completion = (struct completion *)obj;
 
-    return !list_empty( &completion->queue );
+    return !list_empty( &completion->queue ) || completion->abandoned;
 }
 
 static unsigned int completion_map_access( struct object *obj, unsigned int access )
@@ -141,6 +159,7 @@ static struct completion *create_completion( struct object *root, const struct u
         if (get_error() != STATUS_OBJECT_NAME_EXISTS)
         {
             list_init( &completion->queue );
+            completion->abandoned = 0;
             completion->depth = 0;
         }
     }
@@ -224,7 +243,7 @@ DECL_HANDLER(remove_completion)
 
     entry = list_head( &completion->queue );
     if (!entry)
-        set_error( STATUS_PENDING );
+        set_error( completion->abandoned ? STATUS_ABANDONED_WAIT_0 : STATUS_PENDING );
     else
     {
         list_remove( entry );
-- 
2.26.2




More information about the wine-devel mailing list