Similar to how qemu_set_fd_handler2() allows defining a function which checks whether the recipient is ready to read, add aio_set_fd_handler2() with a parameter for defining such a callback.
Signed-off-by: Max Reitz <mre...@redhat.com> --- aio-posix.c | 26 ++++++++++++++++++++------ include/block/aio.h | 12 ++++++++++++ include/qemu/main-loop.h | 1 - 3 files changed, 32 insertions(+), 7 deletions(-) diff --git a/aio-posix.c b/aio-posix.c index f921d4f..267df35 100644 --- a/aio-posix.c +++ b/aio-posix.c @@ -21,6 +21,7 @@ struct AioHandler { GPollFD pfd; + IOCanReadHandler *io_read_poll; IOHandler *io_read; IOHandler *io_write; int deleted; @@ -42,11 +43,12 @@ static AioHandler *find_aio_handler(AioContext *ctx, int fd) return NULL; } -void aio_set_fd_handler(AioContext *ctx, - int fd, - IOHandler *io_read, - IOHandler *io_write, - void *opaque) +void aio_set_fd_handler2(AioContext *ctx, + int fd, + IOCanReadHandler *io_read_poll, + IOHandler *io_read, + IOHandler *io_write, + void *opaque) { AioHandler *node; @@ -80,6 +82,7 @@ void aio_set_fd_handler(AioContext *ctx, g_source_add_poll(&ctx->source, &node->pfd); } /* Update handler with latest information */ + node->io_read_poll = io_read_poll; node->io_read = io_read; node->io_write = io_write; node->opaque = opaque; @@ -92,6 +95,15 @@ void aio_set_fd_handler(AioContext *ctx, aio_notify(ctx); } +void aio_set_fd_handler(AioContext *ctx, + int fd, + IOHandler *io_read, + IOHandler *io_write, + void *opaque) +{ + aio_set_fd_handler2(ctx, fd, NULL, io_read, io_write, opaque); +} + void aio_set_event_notifier(AioContext *ctx, EventNotifier *notifier, EventNotifierHandler *io_read) @@ -108,7 +120,9 @@ bool aio_pending(AioContext *ctx) int revents; revents = node->pfd.revents & node->pfd.events; - if (revents & (G_IO_IN | G_IO_HUP | G_IO_ERR) && node->io_read) { + if (revents & (G_IO_IN | G_IO_HUP | G_IO_ERR) && node->io_read && + (!node->io_read_poll || node->io_read_poll(node->opaque))) + { return true; } if (revents & (G_IO_OUT | G_IO_ERR) && node->io_write) { diff --git a/include/block/aio.h b/include/block/aio.h index a92511b..0a0ca14 100644 --- a/include/block/aio.h +++ b/include/block/aio.h @@ -44,6 +44,7 @@ void qemu_aio_release(void *p); typedef struct AioHandler AioHandler; typedef void QEMUBHFunc(void *opaque); typedef void IOHandler(void *opaque); +typedef int IOCanReadHandler(void *opaque); struct AioContext { GSource source; @@ -230,6 +231,17 @@ void aio_set_fd_handler(AioContext *ctx, IOHandler *io_read, IOHandler *io_write, void *opaque); + +/* Similar to aio_set_fd_handler(), only that this form additionally allows + * registering an IOCanReadHandler which can be used for temporarily inhibiting + * io_read() from being called. + */ +void aio_set_fd_handler2(AioContext *ctx, + int fd, + IOCanReadHandler *io_read_poll, + IOHandler *io_read, + IOHandler *io_write, + void *opaque); #endif /* Register an event notifier and associated callbacks. Behaves very similarly diff --git a/include/qemu/main-loop.h b/include/qemu/main-loop.h index 6f0200a..01273f6 100644 --- a/include/qemu/main-loop.h +++ b/include/qemu/main-loop.h @@ -169,7 +169,6 @@ void qemu_del_wait_object(HANDLE handle, WaitObjectFunc *func, void *opaque); /* async I/O support */ typedef void IOReadHandler(void *opaque, const uint8_t *buf, int size); -typedef int IOCanReadHandler(void *opaque); /** * qemu_set_fd_handler2: Register a file descriptor with the main loop -- 1.9.3