From: Jinoh Kang Subject: [RFC PATCH v2 02/11] server: Add a helper function to trigger synchronous completion of I/O via APC_ASYNC_IO. Message-Id: Date: Sat, 22 Jan 2022 23:36:19 +0900 In-Reply-To: <1e0d520b-0f60-1323-3305-4f884fb121a1@gmail.com> References: <1e0d520b-0f60-1323-3305-4f884fb121a1@gmail.com> Signed-off-by: Jinoh Kang --- Notes: This patch was necessary since we have to reuse APC for synchronous I/O. The previous approach without APC would completely obviate the need for this function. server/async.c | 17 +++++++++++++++++ server/file.h | 1 + 2 files changed, 18 insertions(+) diff --git a/server/async.c b/server/async.c index aa6d50cde75..5d0857f3eec 100644 --- a/server/async.c +++ b/server/async.c @@ -383,6 +383,23 @@ obj_handle_t async_handoff( struct async *async, data_size_t *result, int force_ return async->wait_handle; } +/* Set up synchronous completion of I/O via the APC_ASYNC_IO system APC. + * This function is intended to be called immediately before async_handoff(), + * and expects the last error status to be STATUS_ALERTED. + * + * The information argument can be used to pass extra information to the client + * (e.g. whether the socket is in non-blocking mode). + */ +void async_start_sync_io_request( struct async *async, data_size_t information ) +{ + assert( get_error() == STATUS_ALERTED ); + assert( async->thread == current ); + assert( !async->pending ); + + async->direct_result = 0; /* force APC to fire off */ + async->iosb->result = information; +} + /* complete a request-based async with a pre-allocated buffer */ void async_request_complete( struct async *async, unsigned int status, data_size_t result, data_size_t out_size, void *out_data ) diff --git a/server/file.h b/server/file.h index 1d830cd3d6f..34930b87b5d 100644 --- a/server/file.h +++ b/server/file.h @@ -234,6 +234,7 @@ extern void async_set_initial_status( struct async *async, unsigned int status ) extern void async_wake_obj( struct async *async ); extern int async_waiting( struct async_queue *queue ); extern void async_terminate( struct async *async, unsigned int status ); +extern void async_start_sync_io_request( struct async *async, data_size_t information ); extern void async_request_complete( struct async *async, unsigned int status, data_size_t result, data_size_t out_size, void *out_data ); extern void async_request_complete_alloc( struct async *async, unsigned int status, data_size_t result, -- 2.31.1