[PATCH v4 1/8] server: Actually set initial status in set_async_direct_result handler.

Jinoh Kang jinoh.kang.kr at gmail.com
Thu Mar 3 07:30:17 CST 2022


Commit 15483b1a126 (server: Allow calling async_handoff() with status
code STATUS_ALERTED., 2022-02-10) introduced the set_async_direct_result
handler which calls async_set_initial_status().

However, the async_set_initial_status() call does nothing since
async->terminated is set, leaving the async in a confusing state
(unknown_status = 1 but pending/completed).

So far, this issue is unlikely to have been a problem in practice for
the following reasons:

1. async_set_initial_status() would have unset unknown_status, but it
   remains set instead.  This is usually not a problem, since
   unknown_status is usually ever read by code paths effectively
   unreachable for non-device (e.g. socket) asyncs.

   It would still potentially allow set_async_direct_result to be called
   multiple times, but it wouldn't actually happen in practice unless
   something goes wrong.

2. async_set_initial_status() would have set initial_status; however,
   it is left with the default value STATUS_PENDING.  If the actual
   status is something other than that, the handler closes the wait
   handle and async_satisfied (the only realconsumer of initial_status)
   would never be called anyway.

For reasons above, this issue is not effectively observable or testable.
Nonetheless, the current code does leave the async object in an
inconsistent state.

Fix this by removing the !async->terminated check in
async_set_initial_status().

Signed-off-by: Jinoh Kang <jinoh.kang.kr at gmail.com>
---

Notes:
    v1 -> v2: no changes
    v2 -> v3: no changes
    v3 -> v4: reuse async_set_initial_status() per feedback

 server/async.c | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/server/async.c b/server/async.c
index 7d0ff10f7a4..e92d4583c1e 100644
--- a/server/async.c
+++ b/server/async.c
@@ -303,11 +303,8 @@ struct async *create_async( struct fd *fd, struct thread *thread, const async_da
 void async_set_initial_status( struct async *async, unsigned int status )
 {
     assert( async->unknown_status );
-    if (!async->terminated)
-    {
-        async->initial_status = status;
-        async->unknown_status = 0;
-    }
+    async->initial_status = status;
+    async->unknown_status = 0;
 }
 
 void set_async_pending( struct async *async )
-- 
2.34.1




More information about the wine-devel mailing list