From: Stefan Hajnoczi <[email protected]> The ppoll and epoll file descriptor monitoring implementations rely on the event loop's generic file descriptor, timer, and BH dispatch code to invoke user callbacks.
The io_uring file descriptor monitoring implementation will need io_uring-specific dispatch logic for CQE handlers for custom SQEs. Introduce a new FDMonOps ->dispatch() callback that allows file descriptor monitoring implementations to invoke user callbacks. The next patch will use this new callback. Signed-off-by: Stefan Hajnoczi <[email protected]> Message-ID: <[email protected]> Reviewed-by: Kevin Wolf <[email protected]> Signed-off-by: Kevin Wolf <[email protected]> --- include/block/aio.h | 19 +++++++++++++++++++ util/aio-posix.c | 9 +++++++++ 2 files changed, 28 insertions(+) diff --git a/include/block/aio.h b/include/block/aio.h index 13b6d34238..fc1a3c06e2 100644 --- a/include/block/aio.h +++ b/include/block/aio.h @@ -107,6 +107,25 @@ typedef struct { */ bool (*need_wait)(AioContext *ctx); + /* + * dispatch: + * @ctx: the AioContext + * + * Dispatch any work that is specific to this file descriptor monitoring + * implementation. Usually the event loop's generic file descriptor + * monitoring, BH, and timer dispatching code is sufficient, but file + * descriptor monitoring implementations offering additional functionality + * may need to implement this function for custom behavior. Called at a + * point in the event loop when it is safe to invoke user-defined + * callbacks. + * + * This function is optional and may be NULL. + * + * Returns: true if progress was made (see aio_poll()'s return value), + * false otherwise. + */ + bool (*dispatch)(AioContext *ctx); + /* * gsource_prepare: * @ctx: the AioContext diff --git a/util/aio-posix.c b/util/aio-posix.c index c0285a26a3..6ff36b6e51 100644 --- a/util/aio-posix.c +++ b/util/aio-posix.c @@ -385,10 +385,15 @@ void aio_dispatch(AioContext *ctx) AioHandlerList ready_list = QLIST_HEAD_INITIALIZER(ready_list); qemu_lockcnt_inc(&ctx->list_lock); + aio_bh_poll(ctx); ctx->fdmon_ops->gsource_dispatch(ctx, &ready_list); + if (ctx->fdmon_ops->dispatch) { + ctx->fdmon_ops->dispatch(ctx); + } + /* block_ns is 0 because polling is disabled in the glib event loop */ aio_dispatch_ready_handlers(ctx, &ready_list, 0); @@ -707,6 +712,10 @@ bool aio_poll(AioContext *ctx, bool blocking) block_ns = qemu_clock_get_ns(QEMU_CLOCK_REALTIME) - start; } + if (ctx->fdmon_ops->dispatch) { + progress |= ctx->fdmon_ops->dispatch(ctx); + } + progress |= aio_bh_poll(ctx); progress |= aio_dispatch_ready_handlers(ctx, &ready_list, block_ns); -- 2.51.1
