From: Jinoh Kang <jinoh.kang.kr@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@winehq.org
To unsubscribe send an email to wine-gitlab-leave@winehq.or
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