From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from [140.186.70.92] (port=60907 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1PeowJ-0006qv-Sy for qemu-devel@nongnu.org; Mon, 17 Jan 2011 08:16:09 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1PeowI-0006CH-1E for qemu-devel@nongnu.org; Mon, 17 Jan 2011 08:16:07 -0500 Received: from e9.ny.us.ibm.com ([32.97.182.139]:37384) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1PeowH-0006CD-T8 for qemu-devel@nongnu.org; Mon, 17 Jan 2011 08:16:05 -0500 Received: from d01dlp02.pok.ibm.com (d01dlp02.pok.ibm.com [9.56.224.85]) by e9.ny.us.ibm.com (8.14.4/8.13.1) with ESMTP id p0HCplpL018997 for ; Mon, 17 Jan 2011 07:51:51 -0500 Received: from d01relay01.pok.ibm.com (d01relay01.pok.ibm.com [9.56.227.233]) by d01dlp02.pok.ibm.com (Postfix) with ESMTP id F30A24DE803F for ; Mon, 17 Jan 2011 08:12:51 -0500 (EST) Received: from d01av04.pok.ibm.com (d01av04.pok.ibm.com [9.56.224.64]) by d01relay01.pok.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id p0HDG4BV309448 for ; Mon, 17 Jan 2011 08:16:04 -0500 Received: from d01av04.pok.ibm.com (loopback [127.0.0.1]) by d01av04.pok.ibm.com (8.14.4/8.13.1/NCO v10.0 AVout) with ESMTP id p0HDG4gb030008 for ; Mon, 17 Jan 2011 08:16:04 -0500 From: Michael Roth Date: Mon, 17 Jan 2011 07:14:55 -0600 Message-Id: <1295270117-24760-2-git-send-email-mdroth@linux.vnet.ibm.com> In-Reply-To: <1295270117-24760-1-git-send-email-mdroth@linux.vnet.ibm.com> References: <1295270117-24760-1-git-send-email-mdroth@linux.vnet.ibm.com> Subject: [Qemu-devel] [RFC][PATCH v6 01/23] Move code related to fd handlers into utility functions List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: agl@linux.vnet.ibm.com, stefanha@linux.vnet.ibm.com, Jes.Sorensen@redhat.com, marcel.mittelstaedt@de.ibm.com, mdroth@linux.vnet.ibm.com, markus_mueller@de.ibm.com, aliguori@linux.vnet.ibm.com, ryanh@us.ibm.com, abeekhof@redhat.com This allows us to implement an i/o loop outside of vl.c that can interact with objects that use qemu_set_fd_handler() Signed-off-by: Michael Roth --- Makefile.objs | 2 +- qemu-char.h | 4 ++ qemu-ioh.c | 115 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ qemu-ioh.h | 34 +++++++++++++++++ vl.c | 86 ++++++++---------------------------------- 5 files changed, 170 insertions(+), 71 deletions(-) create mode 100644 qemu-ioh.c create mode 100644 qemu-ioh.h diff --git a/Makefile.objs b/Makefile.objs index c3e52c5..0078921 100644 --- a/Makefile.objs +++ b/Makefile.objs @@ -14,7 +14,7 @@ oslib-obj-$(CONFIG_POSIX) += oslib-posix.o # block-obj-y is code used by both qemu system emulation and qemu-img block-obj-y = cutils.o cache-utils.o qemu-malloc.o qemu-option.o module.o -block-obj-y += nbd.o block.o aio.o aes.o qemu-config.o +block-obj-y += nbd.o block.o aio.o aes.o qemu-config.o qemu-ioh.o block-obj-$(CONFIG_POSIX) += posix-aio-compat.o block-obj-$(CONFIG_LINUX_AIO) += linux-aio.o diff --git a/qemu-char.h b/qemu-char.h index e6ee6c4..7d0794a 100644 --- a/qemu-char.h +++ b/qemu-char.h @@ -7,6 +7,7 @@ #include "qemu-config.h" #include "qobject.h" #include "qstring.h" +#include "qemu-ioh.h" /* character device */ @@ -118,4 +119,7 @@ int qemu_set_fd_handler(int fd, IOHandler *fd_read, IOHandler *fd_write, void *opaque); +void qemu_get_fdset(int *nfds, fd_set *rfds, fd_set *wfds, fd_set *xfds); +void qemu_process_fd_handlers(const fd_set *rfds, const fd_set *wfds, + const fd_set *xfds); #endif diff --git a/qemu-ioh.c b/qemu-ioh.c new file mode 100644 index 0000000..cc71470 --- /dev/null +++ b/qemu-ioh.c @@ -0,0 +1,115 @@ +/* + * QEMU System Emulator + * + * Copyright (c) 2003-2008 Fabrice Bellard + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include "qemu-ioh.h" +#include "qlist.h" + +/* XXX: fd_read_poll should be suppressed, but an API change is + necessary in the character devices to suppress fd_can_read(). */ +int qemu_set_fd_handler3(void *ioh_record_list, + int fd, + IOCanReadHandler *fd_read_poll, + IOHandler *fd_read, + IOHandler *fd_write, + void *opaque) +{ + QLIST_HEAD(, IOHandlerRecord) *io_handlers_ptr = ioh_record_list; + IOHandlerRecord *ioh; + + if (!fd_read && !fd_write) { + QLIST_FOREACH(ioh, io_handlers_ptr, next) { + if (ioh->fd == fd) { + ioh->deleted = 1; + break; + } + } + } else { + QLIST_FOREACH(ioh, io_handlers_ptr, next) { + if (ioh->fd == fd) + goto found; + } + ioh = qemu_mallocz(sizeof(IOHandlerRecord)); + QLIST_INSERT_HEAD(io_handlers_ptr, ioh, next); + found: + ioh->fd = fd; + ioh->fd_read_poll = fd_read_poll; + ioh->fd_read = fd_read; + ioh->fd_write = fd_write; + ioh->opaque = opaque; + ioh->deleted = 0; + } + return 0; +} + +/* add entries from ioh record list to fd sets. nfds and fd sets + * should be cleared/reset by caller if desired. set a particular + * fdset to NULL to ignore fd events of that type + */ +void qemu_get_fdset2(void *ioh_record_list, int *nfds, fd_set *rfds, + fd_set *wfds, fd_set *xfds) +{ + QLIST_HEAD(, IOHandlerRecord) *io_handlers = ioh_record_list; + IOHandlerRecord *ioh; + + QLIST_FOREACH(ioh, io_handlers, next) { + if (ioh->deleted) + continue; + if ((rfds != NULL && ioh->fd_read) && + (!ioh->fd_read_poll || + ioh->fd_read_poll(ioh->opaque) != 0)) { + FD_SET(ioh->fd, rfds); + if (ioh->fd > *nfds) + *nfds = ioh->fd; + } + if (wfds != NULL && ioh->fd_write) { + FD_SET(ioh->fd, wfds); + if (ioh->fd > *nfds) + *nfds = ioh->fd; + } + } +} + +/* execute registered handlers for r/w events in the provided fdsets. unset + * handlers are cleaned up here as well + */ +void qemu_process_fd_handlers2(void *ioh_record_list, const fd_set *rfds, + const fd_set *wfds, const fd_set *xfds) +{ + QLIST_HEAD(, IOHandlerRecord) *io_handlers = ioh_record_list; + IOHandlerRecord *ioh, *pioh; + + QLIST_FOREACH_SAFE(ioh, io_handlers, next, pioh) { + if (!ioh->deleted && ioh->fd_read && FD_ISSET(ioh->fd, rfds)) { + ioh->fd_read(ioh->opaque); + } + if (!ioh->deleted && ioh->fd_write && FD_ISSET(ioh->fd, wfds)) { + ioh->fd_write(ioh->opaque); + } + + /* Do this last in case read/write handlers marked it for deletion */ + if (ioh->deleted) { + QLIST_REMOVE(ioh, next); + qemu_free(ioh); + } + } +} diff --git a/qemu-ioh.h b/qemu-ioh.h new file mode 100644 index 0000000..7c6e833 --- /dev/null +++ b/qemu-ioh.h @@ -0,0 +1,34 @@ +#ifndef QEMU_IOH_H +#define QEMU_IOH_H + +#include "qemu-common.h" +#include "qlist.h" + +/* common i/o loop definitions */ + +typedef struct IOHandlerRecord { + int fd; + IOCanReadHandler *fd_read_poll; + IOHandler *fd_read; + IOHandler *fd_write; + int deleted; + void *opaque; + /* temporary data */ + struct pollfd *ufd; + QLIST_ENTRY(IOHandlerRecord) next; +} IOHandlerRecord; + +/* XXX: fd_read_poll should be suppressed, but an API change is + necessary in the character devices to suppress fd_can_read(). */ +int qemu_set_fd_handler3(void *io_handlers_ptr, + int fd, + IOCanReadHandler *fd_read_poll, + IOHandler *fd_read, + IOHandler *fd_write, + void *opaque); +void qemu_get_fdset2(void *ioh_record_list, int *nfds, fd_set *rfds, + fd_set *wfds, fd_set *xfds); +void qemu_process_fd_handlers2(void *ioh_record_list, const fd_set *rfds, + const fd_set *wfds, const fd_set *xfds); + +#endif diff --git a/vl.c b/vl.c index 0292184..d3bdfec 100644 --- a/vl.c +++ b/vl.c @@ -148,6 +148,7 @@ int main(int argc, char **argv) #include "qemu-config.h" #include "qemu-objects.h" #include "qemu-options.h" +#include "qemu-ioh.h" #ifdef CONFIG_VIRTFS #include "fsdev/qemu-fsdev.h" #endif @@ -1007,18 +1008,6 @@ void pcmcia_info(Monitor *mon) /***********************************************************/ /* I/O handling */ -typedef struct IOHandlerRecord { - int fd; - IOCanReadHandler *fd_read_poll; - IOHandler *fd_read; - IOHandler *fd_write; - int deleted; - void *opaque; - /* temporary data */ - struct pollfd *ufd; - QLIST_ENTRY(IOHandlerRecord) next; -} IOHandlerRecord; - static QLIST_HEAD(, IOHandlerRecord) io_handlers = QLIST_HEAD_INITIALIZER(io_handlers); @@ -1031,31 +1020,8 @@ int qemu_set_fd_handler2(int fd, IOHandler *fd_write, void *opaque) { - IOHandlerRecord *ioh; - - 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 = qemu_mallocz(sizeof(IOHandlerRecord)); - QLIST_INSERT_HEAD(&io_handlers, ioh, next); - found: - ioh->fd = fd; - ioh->fd_read_poll = fd_read_poll; - ioh->fd_read = fd_read; - ioh->fd_write = fd_write; - ioh->opaque = opaque; - ioh->deleted = 0; - } - return 0; + return qemu_set_fd_handler3(&io_handlers, fd, fd_read_poll, fd_read, + fd_write, opaque); } int qemu_set_fd_handler(int fd, @@ -1066,6 +1032,17 @@ int qemu_set_fd_handler(int fd, return qemu_set_fd_handler2(fd, NULL, fd_read, fd_write, opaque); } +void qemu_get_fdset(int *nfds, fd_set *rfds, fd_set *wfds, fd_set *xfds) +{ + return qemu_get_fdset2(&io_handlers, nfds, rfds, wfds, xfds); +} + +void qemu_process_fd_handlers(const fd_set *rfds, const fd_set *wfds, + const fd_set *xfds) +{ + return qemu_process_fd_handlers2(&io_handlers, rfds, wfds, xfds); +} + /***********************************************************/ /* machine registration */ @@ -1295,7 +1272,6 @@ void qemu_system_powerdown_request(void) void main_loop_wait(int nonblocking) { - IOHandlerRecord *ioh; fd_set rfds, wfds, xfds; int ret, nfds; struct timeval tv; @@ -1316,22 +1292,7 @@ void main_loop_wait(int nonblocking) FD_ZERO(&rfds); FD_ZERO(&wfds); FD_ZERO(&xfds); - QLIST_FOREACH(ioh, &io_handlers, next) { - if (ioh->deleted) - continue; - if (ioh->fd_read && - (!ioh->fd_read_poll || - ioh->fd_read_poll(ioh->opaque) != 0)) { - FD_SET(ioh->fd, &rfds); - if (ioh->fd > nfds) - nfds = ioh->fd; - } - if (ioh->fd_write) { - FD_SET(ioh->fd, &wfds); - if (ioh->fd > nfds) - nfds = ioh->fd; - } - } + qemu_get_fdset(&nfds, &rfds, &wfds, &xfds); tv.tv_sec = timeout / 1000; tv.tv_usec = (timeout % 1000) * 1000; @@ -1342,22 +1303,7 @@ void main_loop_wait(int nonblocking) ret = select(nfds + 1, &rfds, &wfds, &xfds, &tv); qemu_mutex_lock_iothread(); if (ret > 0) { - IOHandlerRecord *pioh; - - QLIST_FOREACH_SAFE(ioh, &io_handlers, next, pioh) { - if (!ioh->deleted && ioh->fd_read && FD_ISSET(ioh->fd, &rfds)) { - ioh->fd_read(ioh->opaque); - } - if (!ioh->deleted && ioh->fd_write && FD_ISSET(ioh->fd, &wfds)) { - ioh->fd_write(ioh->opaque); - } - - /* Do this last in case read/write handlers marked it for deletion */ - if (ioh->deleted) { - QLIST_REMOVE(ioh, next); - qemu_free(ioh); - } - } + qemu_process_fd_handlers(&rfds, &wfds, &xfds); } slirp_select_poll(&rfds, &wfds, &xfds, (ret < 0)); -- 1.7.0.4