[PATCH v2 0/1] MR499: Draft: server: Allow cancelling alerted asyncs.
-- v2: server: Allow cancelling alerted asyncs. https://gitlab.winehq.org/wine/wine/-/merge_requests/499
From: Jinoh Kang <jinoh.kang.kr(a)gmail.com> --- server/async.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/server/async.c b/server/async.c index 4832d69b7bf..8b9afe3b5a0 100644 --- a/server/async.c +++ b/server/async.c @@ -44,6 +44,7 @@ struct async struct fd *fd; /* fd associated with an unqueued async */ struct timeout_user *timeout; unsigned int timeout_status; /* status to report upon timeout */ + unsigned int terminate_status;/* pending termination status, or STATUS_PENDING */ struct event *event; async_data_t data; /* data for async I/O call */ struct iosb *iosb; /* I/O status block */ @@ -165,6 +166,11 @@ void async_terminate( struct async *async, unsigned int status ) { struct iosb *iosb = async->iosb; + if (status != STATUS_ALERTED && async->terminate_status == STATUS_PENDING) + { + async->terminate_status = status; + } + if (async->terminated) return; async->terminated = 1; @@ -268,6 +274,7 @@ struct async *create_async( struct fd *fd, struct thread *thread, const async_da async->queue = NULL; async->fd = (struct fd *)grab_object( fd ); async->initial_status = STATUS_PENDING; + async->terminate_status = STATUS_PENDING; async->signaled = 0; async->pending = 1; async->wait_handle = 0; @@ -497,7 +504,15 @@ void async_set_result( struct object *obj, unsigned int status, apc_param_t tota { async->terminated = 0; async->alerted = 0; - async_reselect( async ); + + if (async->terminate_status != STATUS_PENDING) + { + async_terminate( async, async->terminate_status ); + } + else + { + async_reselect( async ); + } } else { -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/499
On Fri, Jul 22, 2022, 2:55 AM Jinoh Kang <wine(a)gitlab.winehq.org> wrote:
From: Jinoh Kang <jinoh.kang.kr(a)gmail.com>
--- server/async.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-)
diff --git a/server/async.c b/server/async.c index 4832d69b7bf..8b9afe3b5a0 100644 --- a/server/async.c +++ b/server/async.c @@ -44,6 +44,7 @@ struct async struct fd *fd; /* fd associated with an unqueued async */ struct timeout_user *timeout; unsigned int timeout_status; /* status to report upon timeout */ + unsigned int terminate_status;/* pending termination status, or STATUS_PENDING */ struct event *event; async_data_t data; /* data for async I/O call */ struct iosb *iosb; /* I/O status block */ @@ -165,6 +166,11 @@ void async_terminate( struct async *async, unsigned int status ) { struct iosb *iosb = async->iosb;
+ if (status != STATUS_ALERTED && async->terminate_status == STATUS_PENDING) + { + async->terminate_status = status; + } + if (async->terminated) return;
async->terminated = 1; @@ -268,6 +274,7 @@ struct async *create_async( struct fd *fd, struct thread *thread, const async_da async->queue = NULL; async->fd = (struct fd *)grab_object( fd ); async->initial_status = STATUS_PENDING; + async->terminate_status = STATUS_PENDING; async->signaled = 0; async->pending = 1; async->wait_handle = 0; @@ -497,7 +504,15 @@ void async_set_result( struct object *obj, unsigned int status, apc_param_t tota { async->terminated = 0; async->alerted = 0; - async_reselect( async ); + + if (async->terminate_status != STATUS_PENDING) + { + async_terminate( async, async->terminate_status ); + } + else + { + async_reselect( async ); + } } else { -- GitLab
https://gitlab.winehq.org/wine/wine/-/merge_requests/499 _______________________________________________ wine-gitlab mailing list -- wine-gitlab(a)winehq.org To unsubscribe send an email to wine-gitlab-leave(a)winehq.or <wine-gitlab-leave(a)winehq.org>
I believe this can use some tests, but I'm not sure how to do them other than stress testing, since this is effectively a race condition bug. -- Sincerely, Jinoh Kang
participants (3)
-
Jin-oh Kang -
Jinoh Kang -
Jinoh Kang (@iamahuman)