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

Zebediah Figura zfigura at codeweavers.com
Wed Feb 2 17:45:27 CST 2022


On 1/29/22 01:47, Jinoh Kang wrote:
> If the server detects that an I/O request could be completed immediately
> (e.g. the socket to read from already has incoming data), it can now
> return STATUS_ALERTED to allow opportunistic synchronous I/O.
> The Unix side will then attempt to perform I/O in nonblocking mode and
> report back the I/O status to the server with signal_wait_async().
> If the operation returns e.g. EAGAIN or EWOULDBLOCK, the client can opt
> to either abandon the request (by specifying an error status) or poll
> for it in the server as usual (by waiting on the wait handle).
> 
> Without such mechanism in place, the client cannot safely perform
> immediately satiable I/O operations synchronously, since it can
> potentially conflict with other pending I/O operations that have already
> been queued.
> 
> Signed-off-by: Jinoh Kang <jinoh.kang.kr at gmail.com>
> ---
> 
> Notes:
>      v2 -> v3: set async->alerted = 1
>      v3 -> v4: unchanged
> 
>   server/async.c | 24 ++++++++++++++++++++++++
>   1 file changed, 24 insertions(+)
> 
> diff --git a/server/async.c b/server/async.c
> index 7aef28355f0..e169bb23225 100644
> --- a/server/async.c
> +++ b/server/async.c
> @@ -338,6 +338,30 @@ obj_handle_t async_handoff( struct async *async, data_size_t *result, int force_
>           return async->wait_handle;
>       }
>   
> +    if (!async->pending && get_error() == STATUS_ALERTED)

Why "!async->pending"?

> +    {
> +        /* Give the client opportunity to complete synchronously.
> +         * If it turns out that the I/O request is not actually immediately satiable,
> +         * the client may then choose to re-queue the async (with STATUS_PENDING).

I'd explicitly mention *how* the async should be requeued here.

> +         */
> +        async->unknown_status = 1;
> +
> +        /* Deactivate async so that it can be safely queued.
> +         * Otherwise, the async will be erroneously alerted the next time
> +         * someone calls async_wake_up() on the queue.

Not to put too much weight on my own perspective, but I think it's 
clearer to explain *why* to do something, rather than why not. In this 
case, what we're doing is mimicking a normal "alert" case, except that 
we're not using an APC.

> +         *
> +         * Don't use async_terminate() here since we'd like to leave the IOSB
> +         * status as STATUS_PENDING.  

Wait, why is this important?

> Also we certainly don't want APC_ASYNC_IO
> +         * to fire in any circumstances.
> +         */
> +        async->terminated = 1;
> +        async->alerted = 1;
> +
> +        async_reselect( async );
> +
> +        return async->wait_handle;
> +    }
> +
>       async->initial_status = get_error();
>   
>       if (!async->pending && NT_ERROR( get_error() ))



More information about the wine-devel mailing list