From f3926945c85689e8af324c0db0b39be771dbbebb Mon Sep 17 00:00:00 2001 From: Fam Zheng Date: Mon, 7 Sep 2015 11:28:58 +0800 Subject: iohandler: Use aio API iohandler.c shares the same interface with aio, but with duplicated code. It's better to rebase iohandler, also because that aio is a more friendly interface to multi-threads. Create a global AioContext instance and let its GSource handle the iohandler events. Signed-off-by: Fam Zheng Message-Id: <1441596538-4412-1-git-send-email-famz@redhat.com> Signed-off-by: Paolo Bonzini --- iohandler.c | 111 ++++++++---------------------------------------------------- 1 file changed, 15 insertions(+), 96 deletions(-) (limited to 'iohandler.c') diff --git a/iohandler.c b/iohandler.c index 826f713e9f..55f8501524 100644 --- a/iohandler.c +++ b/iohandler.c @@ -32,111 +32,30 @@ #include #endif -typedef struct IOHandlerRecord { - IOHandler *fd_read; - IOHandler *fd_write; - void *opaque; - QLIST_ENTRY(IOHandlerRecord) next; - int fd; - int pollfds_idx; - bool deleted; -} IOHandlerRecord; - -static QLIST_HEAD(, IOHandlerRecord) io_handlers = - QLIST_HEAD_INITIALIZER(io_handlers); +/* This context runs on top of main loop. We can't reuse qemu_aio_context + * because iohandlers mustn't be polled by aio_poll(qemu_aio_context). */ +static AioContext *iohandler_ctx; -void qemu_set_fd_handler(int fd, - IOHandler *fd_read, - IOHandler *fd_write, - void *opaque) +static void iohandler_init(void) { - IOHandlerRecord *ioh; - - assert(fd >= 0); - - if (!fd_read && !fd_write) { - QLIST_FOREACH(ioh, &io_handlers, next) { - if (ioh->fd == fd) { - ioh->deleted = 1; - break; - } - } - } else { - QLIST_FOREACH(ioh, &io_handlers, next) { - if (ioh->fd == fd) - goto found; - } - ioh = g_malloc0(sizeof(IOHandlerRecord)); - QLIST_INSERT_HEAD(&io_handlers, ioh, next); - found: - ioh->fd = fd; - ioh->fd_read = fd_read; - ioh->fd_write = fd_write; - ioh->opaque = opaque; - ioh->pollfds_idx = -1; - ioh->deleted = 0; - qemu_notify_event(); + if (!iohandler_ctx) { + iohandler_ctx = aio_context_new(&error_abort); } } -void qemu_iohandler_fill(GArray *pollfds) +GSource *iohandler_get_g_source(void) { - IOHandlerRecord *ioh; - - QLIST_FOREACH(ioh, &io_handlers, next) { - int events = 0; - - if (ioh->deleted) - continue; - if (ioh->fd_read) { - events |= G_IO_IN | G_IO_HUP | G_IO_ERR; - } - if (ioh->fd_write) { - events |= G_IO_OUT | G_IO_ERR; - } - if (events) { - GPollFD pfd = { - .fd = ioh->fd, - .events = events, - }; - ioh->pollfds_idx = pollfds->len; - g_array_append_val(pollfds, pfd); - } else { - ioh->pollfds_idx = -1; - } - } + iohandler_init(); + return aio_get_g_source(iohandler_ctx); } -void qemu_iohandler_poll(GArray *pollfds, int ret) +void qemu_set_fd_handler(int fd, + IOHandler *fd_read, + IOHandler *fd_write, + void *opaque) { - if (ret > 0) { - IOHandlerRecord *pioh, *ioh; - - QLIST_FOREACH_SAFE(ioh, &io_handlers, next, pioh) { - int revents = 0; - - if (!ioh->deleted && ioh->pollfds_idx != -1) { - GPollFD *pfd = &g_array_index(pollfds, GPollFD, - ioh->pollfds_idx); - revents = pfd->revents; - } - - if (!ioh->deleted && ioh->fd_read && - (revents & (G_IO_IN | G_IO_HUP | G_IO_ERR))) { - ioh->fd_read(ioh->opaque); - } - if (!ioh->deleted && ioh->fd_write && - (revents & (G_IO_OUT | G_IO_ERR))) { - ioh->fd_write(ioh->opaque); - } - - /* Do this last in case read/write handlers marked it for deletion */ - if (ioh->deleted) { - QLIST_REMOVE(ioh, next); - g_free(ioh); - } - } - } + iohandler_init(); + aio_set_fd_handler(iohandler_ctx, fd, fd_read, fd_write, opaque); } /* reaping of zombies. right now we're not passing the status to -- cgit v1.2.3