[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