From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from [140.186.70.92] (port=38822 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1Q6DqP-0003zM-10 for qemu-devel@nongnu.org; Sat, 02 Apr 2011 23:19:22 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Q6DqJ-0001f5-Bp for qemu-devel@nongnu.org; Sat, 02 Apr 2011 23:19:16 -0400 Received: from mail-wy0-f173.google.com ([74.125.82.173]:42990) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Q6DqI-0001e9-W8 for qemu-devel@nongnu.org; Sat, 02 Apr 2011 23:19:11 -0400 Received: by wyb42 with SMTP id 42so4312223wyb.4 for ; Sat, 02 Apr 2011 20:19:08 -0700 (PDT) MIME-Version: 1.0 In-Reply-To: <1299691270-16328-2-git-send-email-pbonzini@redhat.com> References: <1299691270-16328-1-git-send-email-pbonzini@redhat.com> <1299691270-16328-2-git-send-email-pbonzini@redhat.com> From: Roy Tam Date: Sun, 3 Apr 2011 11:18:48 +0800 Message-ID: Subject: Re: [Qemu-devel] [PATCH 1/2] extract I/O handler lists to iohandler.c Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Paolo Bonzini Cc: qemu-devel@nongnu.org Hi, 2011/3/10 Paolo Bonzini : > Signed-off-by: Paolo Bonzini > --- > =A0 =A0 =A0 =A0I had this patch queued for a while; only today I noticed = the > =A0 =A0 =A0 =A0very similar one in virtagent. > > =A0Makefile.objs | =A0 =A02 +- > =A0iohandler.c =A0 | =A0129 +++++++++++++++++++++++++++++++++++++++++++++= ++++++++++++ > =A0qemu-common.h | =A0 =A03 + > =A0vl.c =A0 =A0 =A0 =A0 =A0| =A0106 ++-----------------------------------= --------- > =A04 files changed, 138 insertions(+), 102 deletions(-) > =A0create mode 100644 iohandler.c > > diff --git a/Makefile.objs b/Makefile.objs > index 9e98a66..f282507 100644 > --- a/Makefile.objs > +++ b/Makefile.objs > @@ -98,7 +98,7 @@ common-obj-y +=3D buffered_file.o migration.o migration= -tcp.o qemu-sockets.o > =A0common-obj-y +=3D qemu-char.o savevm.o #aio.o > =A0common-obj-y +=3D msmouse.o ps2.o > =A0common-obj-y +=3D qdev.o qdev-properties.o > -common-obj-y +=3D block-migration.o > +common-obj-y +=3D block-migration.o iohandler.o > =A0common-obj-y +=3D pflib.o > =A0common-obj-y +=3D bitmap.o bitops.o > > diff --git a/iohandler.c b/iohandler.c > new file mode 100644 > index 0000000..2e30fe3 > --- /dev/null > +++ b/iohandler.c > @@ -0,0 +1,129 @@ > +/* > + * QEMU System Emulator - managing I/O handler > + * > + * 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 includ= ed in > + * all copies or substantial portions of the Software. > + * > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRE= SS OR > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILI= TY, > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHA= LL > + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR = OTHER > + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISI= NG FROM, > + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALING= S IN > + * THE SOFTWARE. > + */ > + > +#include "config-host.h" > +#include "qemu-common.h" > +#include "qemu-char.h" > +#include "qemu-queue.h" > + > +typedef struct IOHandlerRecord { > + =A0 =A0int fd; > + =A0 =A0IOCanReadHandler *fd_read_poll; > + =A0 =A0IOHandler *fd_read; > + =A0 =A0IOHandler *fd_write; > + =A0 =A0int deleted; > + =A0 =A0void *opaque; > + =A0 =A0QLIST_ENTRY(IOHandlerRecord) next; > +} IOHandlerRecord; > + > +static QLIST_HEAD(, IOHandlerRecord) io_handlers =3D > + =A0 =A0QLIST_HEAD_INITIALIZER(io_handlers); > + > + > +/* XXX: fd_read_poll should be suppressed, but an API change is > + =A0 necessary in the character devices to suppress fd_can_read(). */ > +int qemu_set_fd_handler2(int fd, > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 IOCanReadHandler *fd_re= ad_poll, > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 IOHandler *fd_read, > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 IOHandler *fd_write, > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 void *opaque) > +{ > + =A0 =A0IOHandlerRecord *ioh; > + > + =A0 =A0if (!fd_read && !fd_write) { > + =A0 =A0 =A0 =A0QLIST_FOREACH(ioh, &io_handlers, next) { > + =A0 =A0 =A0 =A0 =A0 =A0if (ioh->fd =3D=3D fd) { > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0ioh->deleted =3D 1; > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0break; > + =A0 =A0 =A0 =A0 =A0 =A0} > + =A0 =A0 =A0 =A0} > + =A0 =A0} else { > + =A0 =A0 =A0 =A0QLIST_FOREACH(ioh, &io_handlers, next) { > + =A0 =A0 =A0 =A0 =A0 =A0if (ioh->fd =3D=3D fd) > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0goto found; > + =A0 =A0 =A0 =A0} > + =A0 =A0 =A0 =A0ioh =3D qemu_mallocz(sizeof(IOHandlerRecord)); > + =A0 =A0 =A0 =A0QLIST_INSERT_HEAD(&io_handlers, ioh, next); > + =A0 =A0found: > + =A0 =A0 =A0 =A0ioh->fd =3D fd; > + =A0 =A0 =A0 =A0ioh->fd_read_poll =3D fd_read_poll; > + =A0 =A0 =A0 =A0ioh->fd_read =3D fd_read; > + =A0 =A0 =A0 =A0ioh->fd_write =3D fd_write; > + =A0 =A0 =A0 =A0ioh->opaque =3D opaque; > + =A0 =A0 =A0 =A0ioh->deleted =3D 0; > + =A0 =A0} > + =A0 =A0return 0; > +} > + > +int qemu_set_fd_handler(int fd, > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0IOHandler *fd_read, > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0IOHandler *fd_write, > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0void *opaque) > +{ > + =A0 =A0return qemu_set_fd_handler2(fd, NULL, fd_read, fd_write, opaque)= ; > +} > + > +void qemu_iohandler_fill(int *pnfds, fd_set *readfds, fd_set *writefds, = fd_set *xfds) > +{ > + =A0 =A0IOHandlerRecord *ioh; > + > + =A0 =A0QLIST_FOREACH(ioh, &io_handlers, next) { > + =A0 =A0 =A0 =A0if (ioh->deleted) > + =A0 =A0 =A0 =A0 =A0 =A0continue; > + =A0 =A0 =A0 =A0if (ioh->fd_read && > + =A0 =A0 =A0 =A0 =A0 =A0(!ioh->fd_read_poll || > + =A0 =A0 =A0 =A0 =A0 =A0 ioh->fd_read_poll(ioh->opaque) !=3D 0)) { > + =A0 =A0 =A0 =A0 =A0 =A0FD_SET(ioh->fd, readfds); > + =A0 =A0 =A0 =A0 =A0 =A0if (ioh->fd > *pnfds) > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0*pnfds =3D ioh->fd; > + =A0 =A0 =A0 =A0} > + =A0 =A0 =A0 =A0if (ioh->fd_write) { > + =A0 =A0 =A0 =A0 =A0 =A0FD_SET(ioh->fd, writefds); > + =A0 =A0 =A0 =A0 =A0 =A0if (ioh->fd > *pnfds) > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0*pnfds =3D ioh->fd; > + =A0 =A0 =A0 =A0} > + =A0 =A0} > +} > + > +void qemu_iohandler_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds= , int ret) > +{ > + =A0 =A0if (ret > 0) { > + =A0 =A0 =A0 =A0IOHandlerRecord *pioh, *ioh; > + > + =A0 =A0 =A0 =A0QLIST_FOREACH_SAFE(ioh, &io_handlers, next, pioh) { > + =A0 =A0 =A0 =A0 =A0 =A0if (!ioh->deleted && ioh->fd_read && FD_ISSET(io= h->fd, readfds)) { > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0ioh->fd_read(ioh->opaque); > + =A0 =A0 =A0 =A0 =A0 =A0} > + =A0 =A0 =A0 =A0 =A0 =A0if (!ioh->deleted && ioh->fd_write && FD_ISSET(i= oh->fd, writefds)) { > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0ioh->fd_write(ioh->opaque); > + =A0 =A0 =A0 =A0 =A0 =A0} > + > + =A0 =A0 =A0 =A0 =A0 =A0/* Do this last in case read/write handlers mark= ed it for deletion */ > + =A0 =A0 =A0 =A0 =A0 =A0if (ioh->deleted) { > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0QLIST_REMOVE(ioh, next); > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0qemu_free(ioh); > + =A0 =A0 =A0 =A0 =A0 =A0} > + =A0 =A0 =A0 =A0} > + =A0 =A0} > +} > diff --git a/qemu-common.h b/qemu-common.h > index 40dad52..27855b0 100644 > --- a/qemu-common.h > +++ b/qemu-common.h > @@ -223,6 +223,9 @@ typedef void IOReadHandler(void *opaque, const uint8_= t *buf, int size); > =A0typedef int IOCanReadHandler(void *opaque); > =A0typedef void IOHandler(void *opaque); > > +void qemu_iohandler_fill(int *pnfds, fd_set *readfds, fd_set *writefds, = fd_set *xfds); > +void qemu_iohandler_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds= , int rc); > + This cause compilation error in MinGW: CC qemu-img.o In file included from qemu-img.c:24: qemu-common.h:231: error: syntax error before "fd_set" qemu-common.h:231: warning: function declaration isn't a prototype qemu-common.h:232: error: syntax error before '*' token qemu-common.h:232: warning: function declaration isn't a prototype make: *** [qemu-img.o] Error 1 > =A0struct ParallelIOArg { > =A0 =A0 void *buffer; > =A0 =A0 int count; > diff --git a/vl.c b/vl.c > index b436952..224a564 100644 > --- a/vl.c > +++ b/vl.c > @@ -1023,68 +1023,6 @@ void pcmcia_info(Monitor *mon) > =A0} > > =A0/***********************************************************/ > -/* I/O handling */ > - > -typedef struct IOHandlerRecord { > - =A0 =A0int fd; > - =A0 =A0IOCanReadHandler *fd_read_poll; > - =A0 =A0IOHandler *fd_read; > - =A0 =A0IOHandler *fd_write; > - =A0 =A0int deleted; > - =A0 =A0void *opaque; > - =A0 =A0/* temporary data */ > - =A0 =A0struct pollfd *ufd; > - =A0 =A0QLIST_ENTRY(IOHandlerRecord) next; > -} IOHandlerRecord; > - > -static QLIST_HEAD(, IOHandlerRecord) io_handlers =3D > - =A0 =A0QLIST_HEAD_INITIALIZER(io_handlers); > - > - > -/* XXX: fd_read_poll should be suppressed, but an API change is > - =A0 necessary in the character devices to suppress fd_can_read(). */ > -int qemu_set_fd_handler2(int fd, > - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 IOCanReadHandler *fd_re= ad_poll, > - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 IOHandler *fd_read, > - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 IOHandler *fd_write, > - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 void *opaque) > -{ > - =A0 =A0IOHandlerRecord *ioh; > - > - =A0 =A0if (!fd_read && !fd_write) { > - =A0 =A0 =A0 =A0QLIST_FOREACH(ioh, &io_handlers, next) { > - =A0 =A0 =A0 =A0 =A0 =A0if (ioh->fd =3D=3D fd) { > - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0ioh->deleted =3D 1; > - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0break; > - =A0 =A0 =A0 =A0 =A0 =A0} > - =A0 =A0 =A0 =A0} > - =A0 =A0} else { > - =A0 =A0 =A0 =A0QLIST_FOREACH(ioh, &io_handlers, next) { > - =A0 =A0 =A0 =A0 =A0 =A0if (ioh->fd =3D=3D fd) > - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0goto found; > - =A0 =A0 =A0 =A0} > - =A0 =A0 =A0 =A0ioh =3D qemu_mallocz(sizeof(IOHandlerRecord)); > - =A0 =A0 =A0 =A0QLIST_INSERT_HEAD(&io_handlers, ioh, next); > - =A0 =A0found: > - =A0 =A0 =A0 =A0ioh->fd =3D fd; > - =A0 =A0 =A0 =A0ioh->fd_read_poll =3D fd_read_poll; > - =A0 =A0 =A0 =A0ioh->fd_read =3D fd_read; > - =A0 =A0 =A0 =A0ioh->fd_write =3D fd_write; > - =A0 =A0 =A0 =A0ioh->opaque =3D opaque; > - =A0 =A0 =A0 =A0ioh->deleted =3D 0; > - =A0 =A0} > - =A0 =A0return 0; > -} > - > -int qemu_set_fd_handler(int fd, > - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0IOHandler *fd_read, > - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0IOHandler *fd_write, > - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0void *opaque) > -{ > - =A0 =A0return qemu_set_fd_handler2(fd, NULL, fd_read, fd_write, opaque)= ; > -} > - > -/***********************************************************/ > =A0/* machine registration */ > > =A0static QEMUMachine *first_machine =3D NULL; > @@ -1326,7 +1264,6 @@ void qemu_system_vmstop_request(int reason) > > =A0void main_loop_wait(int nonblocking) > =A0{ > - =A0 =A0IOHandlerRecord *ioh; > =A0 =A0 fd_set rfds, wfds, xfds; > =A0 =A0 int ret, nfds; > =A0 =A0 struct timeval tv; > @@ -1341,56 +1278,23 @@ void main_loop_wait(int nonblocking) > > =A0 =A0 os_host_main_loop_wait(&timeout); > > + =A0 =A0tv.tv_sec =3D timeout / 1000; > + =A0 =A0tv.tv_usec =3D (timeout % 1000) * 1000; > + > =A0 =A0 /* poll any events */ > =A0 =A0 /* XXX: separate device handlers from system ones */ > =A0 =A0 nfds =3D -1; > =A0 =A0 FD_ZERO(&rfds); > =A0 =A0 FD_ZERO(&wfds); > =A0 =A0 FD_ZERO(&xfds); > - =A0 =A0QLIST_FOREACH(ioh, &io_handlers, next) { > - =A0 =A0 =A0 =A0if (ioh->deleted) > - =A0 =A0 =A0 =A0 =A0 =A0continue; > - =A0 =A0 =A0 =A0if (ioh->fd_read && > - =A0 =A0 =A0 =A0 =A0 =A0(!ioh->fd_read_poll || > - =A0 =A0 =A0 =A0 =A0 =A0 ioh->fd_read_poll(ioh->opaque) !=3D 0)) { > - =A0 =A0 =A0 =A0 =A0 =A0FD_SET(ioh->fd, &rfds); > - =A0 =A0 =A0 =A0 =A0 =A0if (ioh->fd > nfds) > - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0nfds =3D ioh->fd; > - =A0 =A0 =A0 =A0} > - =A0 =A0 =A0 =A0if (ioh->fd_write) { > - =A0 =A0 =A0 =A0 =A0 =A0FD_SET(ioh->fd, &wfds); > - =A0 =A0 =A0 =A0 =A0 =A0if (ioh->fd > nfds) > - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0nfds =3D ioh->fd; > - =A0 =A0 =A0 =A0} > - =A0 =A0} > - > - =A0 =A0tv.tv_sec =3D timeout / 1000; > - =A0 =A0tv.tv_usec =3D (timeout % 1000) * 1000; > - > + =A0 =A0qemu_iohandler_fill(&nfds, &rfds, &wfds, &xfds); > =A0 =A0 slirp_select_fill(&nfds, &rfds, &wfds, &xfds); > > =A0 =A0 qemu_mutex_unlock_iothread(); > =A0 =A0 ret =3D select(nfds + 1, &rfds, &wfds, &xfds, &tv); > =A0 =A0 qemu_mutex_lock_iothread(); > - =A0 =A0if (ret > 0) { > - =A0 =A0 =A0 =A0IOHandlerRecord *pioh; > - > - =A0 =A0 =A0 =A0QLIST_FOREACH_SAFE(ioh, &io_handlers, next, pioh) { > - =A0 =A0 =A0 =A0 =A0 =A0if (!ioh->deleted && ioh->fd_read && FD_ISSET(io= h->fd, &rfds)) { > - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0ioh->fd_read(ioh->opaque); > - =A0 =A0 =A0 =A0 =A0 =A0} > - =A0 =A0 =A0 =A0 =A0 =A0if (!ioh->deleted && ioh->fd_write && FD_ISSET(i= oh->fd, &wfds)) { > - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0ioh->fd_write(ioh->opaque); > - =A0 =A0 =A0 =A0 =A0 =A0} > - > - =A0 =A0 =A0 =A0 =A0 =A0/* Do this last in case read/write handlers mark= ed it for deletion */ > - =A0 =A0 =A0 =A0 =A0 =A0if (ioh->deleted) { > - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0QLIST_REMOVE(ioh, next); > - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0qemu_free(ioh); > - =A0 =A0 =A0 =A0 =A0 =A0} > - =A0 =A0 =A0 =A0} > - =A0 =A0} > > + =A0 =A0qemu_iohandler_poll(&rfds, &wfds, &xfds, ret); > =A0 =A0 slirp_select_poll(&rfds, &wfds, &xfds, (ret < 0)); > > =A0 =A0 qemu_run_all_timers(); > -- > 1.7.4 > > > >