[RFC PATCH 1/6] server: Allow calling async_handoff() with status code STATUS_ALERTED.

Zebediah Figura (she/her) zfigura at codeweavers.com
Wed Jan 26 17:52:30 CST 2022


On 1/23/22 11:29, Jinoh Kang wrote:
> +static int async_add_queue( struct object *obj, struct wait_queue_entry *entry )
> +{
> +    struct async *async = (struct async *)obj;
> +    assert( obj->ops == &async_ops );
> +
> +    if (!async->pending && async->terminated && async->alerted)
> +    {
> +        /* The client has failed to complete synchronously (e.g. EWOULDBLOCK).
> +         * Restart the async as fully fledged asynchronous I/O, where
> +         * the completion port notification and APC call will be triggered
> +         * appropriately. */
> +        async->pending = 1;
> +
> +        /* Unset the signaled flag if the client wants to block on this async. */
> +        if (async->blocking) async->signaled = 0;
> +
> +        async_set_result( obj, STATUS_PENDING, 0 );  /* kick it off */
> +    }
> +
> +    return add_queue( obj, entry );
> +}
> +

I'll admit, this kind of thing is why I didn't really want to have to 
try to optimize 3 server calls into 2. Asyncs are already really 
complicated, in terms of the many paths they can take, and it seems like 
no matter what we do they're going to get worse.

Still, I have a potential idea.

What we need to do here is similar to the infrastructure that already 
exists for device asyncs, namely "unknown_status" etc. It would be nice 
to use that instead of reinventing it, and although I haven't tried, it 
seems possible.

async_add_queue() as it is above is not great. I'm not sure that code 
actually works in every case; it definitely increases the mental burden 
even if it does. (Consider for instance that it would be triggered for 
*every* async).

Instead what I'd suggest is to use the request introduced here in every 
case, even if the initial status was pending. This introduces a new 
server call, but it only does so in cases where we already have to wait.

The end result would be not unlike get_next_device_request, which is 
essentially that request combined with some other things (and it doesn't 
deal in async object handles).



More information about the wine-devel mailing list