From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from [140.186.70.92] (port=52951 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1PrtY8-0007ji-Rl for qemu-devel@nongnu.org; Tue, 22 Feb 2011 09:49:14 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1PrtY7-0001R1-9J for qemu-devel@nongnu.org; Tue, 22 Feb 2011 09:49:12 -0500 Received: from mail-vw0-f45.google.com ([209.85.212.45]:33941) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1PrtY7-0001Qt-4q for qemu-devel@nongnu.org; Tue, 22 Feb 2011 09:49:11 -0500 Received: by vws19 with SMTP id 19so2827416vws.4 for ; Tue, 22 Feb 2011 06:49:10 -0800 (PST) Message-ID: <4D63CCDE.7020001@codemonkey.ws> Date: Tue, 22 Feb 2011 08:49:02 -0600 From: Anthony Liguori MIME-Version: 1.0 References: <3d41a2ca603b8132e2496976e89fca09fc246683.1298369272.git.amit.shah@redhat.com> In-Reply-To: <3d41a2ca603b8132e2496976e89fca09fc246683.1298369272.git.amit.shah@redhat.com> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Subject: [Qemu-devel] Re: [PATCH 2/7] iohandlers: Introduce a new API List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Amit Shah Cc: qemu list , Gerd Hoffmann On 02/22/2011 04:18 AM, Amit Shah wrote: > Introduce a new iohandler api that doesn't have multiple callbacks. > Instead, a single callback and a mask of events that got set will be > passed on to the handler. This will ease our transition to a poll() > interface instead of the current select() that happens on the fds. > > Signed-off-by: Amit Shah > --- > iohandler.h | 28 +++++++++++ > vl.c | 144 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > 2 files changed, 172 insertions(+), 0 deletions(-) > create mode 100644 iohandler.h > > diff --git a/iohandler.h b/iohandler.h > new file mode 100644 > index 0000000..6553835 > --- /dev/null > +++ b/iohandler.h > @@ -0,0 +1,28 @@ > +/* > + * Declarations for iohandler functions > + * > + * Copyright Red Hat, Inc. 2011 > + * Copyright Amit Shah 2011 > + * > + * This work is licensed under the terms of the GNU GPL, version 2. See > + * the COPYING file in the top-level directory. > + */ > + > +#ifndef _QEMU_IOHANDLER_H > +#define _QEMU_IOHANDLER_H > + > +/* iohandler masks */ > +#define IOH_MASK_CAN_READ (1U<< 0) > +#define IOH_MASK_READ (1U<< 1) > +#define IOH_MASK_WRITE (1U<< 2) > + > +typedef int IOAllHandler(void *opaque, unsigned int mask); > + > +int assign_iohandler(int fd, IOAllHandler *handler, unsigned int mask, > + void *opaque); > +int remove_iohandler(int fd); > +int update_fd_mask(int fd, unsigned int mask); > +int get_fd_mask(int fd, unsigned int *mask); > As I previously suggested, we should return a connection handle instead of using an fd as an implicit handle. Regards, Anthony Liguori > + > + > +#endif /* _QEMU_IOHANDLER_H */ > diff --git a/vl.c b/vl.c > index e248ec4..9dabee2 100644 > --- a/vl.c > +++ b/vl.c > @@ -2,6 +2,8 @@ > * QEMU System Emulator > * > * Copyright (c) 2003-2008 Fabrice Bellard > + * Copyright (C) 2011 Red Hat, Inc. > + * Copyright (C) 2011 Amit Shah, > * > * Permission is hereby granted, free of charge, to any person obtaining a copy > * of this software and associated documentation files (the "Software"), to deal > @@ -136,6 +138,7 @@ int main(int argc, char **argv) > #include "gdbstub.h" > #include "qemu-timer.h" > #include "qemu-char.h" > +#include "iohandler.h" > #include "cache-utils.h" > #include "block.h" > #include "blockdev.h" > @@ -1030,6 +1033,8 @@ typedef struct IOHandlerRecord { > IOCanReadHandler *fd_read_poll; > IOHandler *fd_read; > IOHandler *fd_write; > + IOAllHandler *fd_iohandler; > + unsigned int mask; > int deleted; > void *opaque; > /* temporary data */ > @@ -1040,6 +1045,97 @@ typedef struct IOHandlerRecord { > static QLIST_HEAD(, IOHandlerRecord) io_handlers_old = > QLIST_HEAD_INITIALIZER(io_handlers_old); > > +static QLIST_HEAD(, IOHandlerRecord) io_handlers = > + QLIST_HEAD_INITIALIZER(io_handlers); > + > +static IOHandlerRecord *find_iohandler(int fd) > +{ > + IOHandlerRecord *ioh; > + > + QLIST_FOREACH(ioh,&io_handlers, next) { > + if (ioh->fd == fd) { > + return ioh; > + } > + } > + return NULL; > +} > + > +static int update_iohandler_mask(IOHandlerRecord *ioh, unsigned int mask) > +{ > + assert(ioh); > + > + ioh->mask = mask; > + return 0; > +} > + > +/* > + * Updates the mask for the fd. Returns 0 on success. > + */ > +int update_fd_mask(int fd, unsigned int mask) > +{ > + IOHandlerRecord *ioh; > + > + ioh = find_iohandler(fd); > + if (!ioh) { > + return -1; > + } > + > + return update_iohandler_mask(ioh, mask); > +} > + > +/* > + * Populates the mask registered in *mask. Only valid if return value > + * is 0. > + */ > +int get_fd_mask(int fd, unsigned int *mask) > +{ > + IOHandlerRecord *ioh; > + > + ioh = find_iohandler(fd); > + if (!ioh) { > + return -1; > + } > + *mask = ioh->mask; > + > + return 0; > +} > + > +/* > + * Assign an iohandler to an fd. Can also be used to update the mask > + * or handler or the opaque pointer and also to delete the iohandler. > + * Returns 0 on success. > + */ > +int assign_iohandler(int fd, IOAllHandler *handler, unsigned int mask, > + void *opaque) > +{ > + IOHandlerRecord *ioh; > + > + ioh = find_iohandler(fd); > + > + if (!handler) { > + if (ioh) { > + ioh->deleted = 1; > + } > + return 0; > + } > + > + if (!ioh) { > + ioh = qemu_mallocz(sizeof(IOHandlerRecord)); > + QLIST_INSERT_HEAD(&io_handlers, ioh, next); > + ioh->fd = fd; > + } > + ioh->fd_iohandler = handler; > + ioh->opaque = opaque; > + update_iohandler_mask(ioh, mask); > + ioh->deleted = 0; > + > + return 0; > +} > + > +int remove_iohandler(int fd) > +{ > + return assign_iohandler(fd, NULL, 0, NULL); > +} > > /* XXX: fd_read_poll should be suppressed, but an API change is > necessary in the character devices to suppress fd_can_read(). */ > @@ -1363,6 +1459,26 @@ void main_loop_wait(int nonblocking) > nfds = ioh->fd; > } > } > + QLIST_FOREACH(ioh,&io_handlers, next) { > + if (ioh->deleted) { > + continue; > + } > + if (ioh->mask& IOH_MASK_READ&& > + (!(ioh->mask& IOH_MASK_CAN_READ) || > + (ioh->fd_iohandler(ioh->opaque, IOH_MASK_CAN_READ) != 0))) { > + > + FD_SET(ioh->fd,&rfds); > + if (ioh->fd> nfds) { > + nfds = ioh->fd; > + } > + } > + if (ioh->mask& IOH_MASK_WRITE) { > + FD_SET(ioh->fd,&wfds); > + if (ioh->fd> nfds) { > + nfds = ioh->fd; > + } > + } > + } > > tv.tv_sec = timeout / 1000; > tv.tv_usec = (timeout % 1000) * 1000; > @@ -1389,6 +1505,34 @@ void main_loop_wait(int nonblocking) > qemu_free(ioh); > } > } > + QLIST_FOREACH_SAFE(ioh,&io_handlers, next, pioh) { > + unsigned int mask; > + > + mask = 0; > + if (!ioh->deleted) { > + if (FD_ISSET(ioh->fd,&rfds)) { > + mask |= IOH_MASK_READ; > + } > + if (FD_ISSET(ioh->fd,&wfds)) { > + mask |= IOH_MASK_WRITE; > + } > + } > + /* > + * Strip out flags the caller didn't ask for -- shouldn't > + * happen since we set rfds and wfds based on the value of > + * ioh->mask anyway. > + */ > + mask&= ioh->mask; > + if (mask) { > + ioh->fd_iohandler(ioh->opaque, mask); > + } > + /* Do this last in case the handler marked it for deletion */ > + if (ioh->deleted) { > + QLIST_REMOVE(ioh, next); > + qemu_free(ioh); > + continue; > + } > + } > } > > slirp_select_poll(&rfds,&wfds,&xfds, (ret< 0)); >