Commit b632dded authored by Jinoh Kang's avatar Jinoh Kang Committed by Alexandre Julliard

server: Actually set initial status in set_async_direct_result handler.

Commit 15483b1a (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 real consumer 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(). Also, remove assert( async->unknown_status ). The client can now trigger the assert() by calling set_async_direct_result on a device async, thereby causing async_set_initial_status() to be called twice. Signed-off-by: 's avatarJinoh Kang <jinoh.kang.kr@gmail.com> Signed-off-by: 's avatarZebediah Figura <zfigura@codeweavers.com> Signed-off-by: 's avatarAlexandre Julliard <julliard@winehq.org>
parent c3023a12
......@@ -302,12 +302,8 @@ struct async *create_async( struct fd *fd, struct thread *thread, const async_da
* the initial status may be STATUS_PENDING */
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 )
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment