Loading Makefile.objs +1 −1 Original line number Diff line number Diff line Loading @@ -98,7 +98,7 @@ common-obj-y += buffered_file.o migration.o migration-tcp.o qemu-sockets.o common-obj-y += qemu-char.o savevm.o #aio.o common-obj-y += msmouse.o ps2.o common-obj-y += qdev.o qdev-properties.o common-obj-y += block-migration.o common-obj-y += block-migration.o iohandler.o common-obj-y += pflib.o common-obj-y += bitmap.o bitops.o Loading iohandler.c 0 → 100644 +129 −0 Original line number Diff line number Diff line /* * 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 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 "config-host.h" #include "qemu-common.h" #include "qemu-char.h" #include "qemu-queue.h" typedef struct IOHandlerRecord { int fd; IOCanReadHandler *fd_read_poll; IOHandler *fd_read; IOHandler *fd_write; int deleted; void *opaque; QLIST_ENTRY(IOHandlerRecord) next; } IOHandlerRecord; static QLIST_HEAD(, IOHandlerRecord) io_handlers = QLIST_HEAD_INITIALIZER(io_handlers); /* 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_handler2(int fd, IOCanReadHandler *fd_read_poll, IOHandler *fd_read, 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; } int qemu_set_fd_handler(int fd, IOHandler *fd_read, IOHandler *fd_write, void *opaque) { return 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) { IOHandlerRecord *ioh; 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, readfds); if (ioh->fd > *pnfds) *pnfds = ioh->fd; } if (ioh->fd_write) { FD_SET(ioh->fd, writefds); if (ioh->fd > *pnfds) *pnfds = ioh->fd; } } } void qemu_iohandler_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds, int ret) { if (ret > 0) { IOHandlerRecord *pioh, *ioh; QLIST_FOREACH_SAFE(ioh, &io_handlers, next, pioh) { if (!ioh->deleted && ioh->fd_read && FD_ISSET(ioh->fd, readfds)) { ioh->fd_read(ioh->opaque); } if (!ioh->deleted && ioh->fd_write && FD_ISSET(ioh->fd, writefds)) { 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-common.h +3 −0 Original line number Diff line number Diff line Loading @@ -227,6 +227,9 @@ typedef void IOReadHandler(void *opaque, const uint8_t *buf, int size); typedef int IOCanReadHandler(void *opaque); typedef 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); struct ParallelIOArg { void *buffer; int count; Loading vl.c +5 −101 Original line number Diff line number Diff line Loading @@ -1022,68 +1022,6 @@ void pcmcia_info(Monitor *mon) "Empty"); } /***********************************************************/ /* 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); /* 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_handler2(int fd, IOCanReadHandler *fd_read_poll, IOHandler *fd_read, 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; } int qemu_set_fd_handler(int fd, IOHandler *fd_read, IOHandler *fd_write, void *opaque) { return qemu_set_fd_handler2(fd, NULL, fd_read, fd_write, opaque); } /***********************************************************/ /* machine registration */ Loading Loading @@ -1343,7 +1281,6 @@ void qemu_system_vmstop_request(int reason) void main_loop_wait(int nonblocking) { IOHandlerRecord *ioh; fd_set rfds, wfds, xfds; int ret, nfds; struct timeval tv; Loading @@ -1358,56 +1295,23 @@ void main_loop_wait(int nonblocking) os_host_main_loop_wait(&timeout); tv.tv_sec = timeout / 1000; tv.tv_usec = (timeout % 1000) * 1000; /* poll any events */ /* XXX: separate device handlers from system ones */ nfds = -1; 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; } } tv.tv_sec = timeout / 1000; tv.tv_usec = (timeout % 1000) * 1000; qemu_iohandler_fill(&nfds, &rfds, &wfds, &xfds); slirp_select_fill(&nfds, &rfds, &wfds, &xfds); qemu_mutex_unlock_iothread(); 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_iohandler_poll(&rfds, &wfds, &xfds, ret); slirp_select_poll(&rfds, &wfds, &xfds, (ret < 0)); qemu_run_all_timers(); Loading Loading
Makefile.objs +1 −1 Original line number Diff line number Diff line Loading @@ -98,7 +98,7 @@ common-obj-y += buffered_file.o migration.o migration-tcp.o qemu-sockets.o common-obj-y += qemu-char.o savevm.o #aio.o common-obj-y += msmouse.o ps2.o common-obj-y += qdev.o qdev-properties.o common-obj-y += block-migration.o common-obj-y += block-migration.o iohandler.o common-obj-y += pflib.o common-obj-y += bitmap.o bitops.o Loading
iohandler.c 0 → 100644 +129 −0 Original line number Diff line number Diff line /* * 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 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 "config-host.h" #include "qemu-common.h" #include "qemu-char.h" #include "qemu-queue.h" typedef struct IOHandlerRecord { int fd; IOCanReadHandler *fd_read_poll; IOHandler *fd_read; IOHandler *fd_write; int deleted; void *opaque; QLIST_ENTRY(IOHandlerRecord) next; } IOHandlerRecord; static QLIST_HEAD(, IOHandlerRecord) io_handlers = QLIST_HEAD_INITIALIZER(io_handlers); /* 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_handler2(int fd, IOCanReadHandler *fd_read_poll, IOHandler *fd_read, 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; } int qemu_set_fd_handler(int fd, IOHandler *fd_read, IOHandler *fd_write, void *opaque) { return 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) { IOHandlerRecord *ioh; 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, readfds); if (ioh->fd > *pnfds) *pnfds = ioh->fd; } if (ioh->fd_write) { FD_SET(ioh->fd, writefds); if (ioh->fd > *pnfds) *pnfds = ioh->fd; } } } void qemu_iohandler_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds, int ret) { if (ret > 0) { IOHandlerRecord *pioh, *ioh; QLIST_FOREACH_SAFE(ioh, &io_handlers, next, pioh) { if (!ioh->deleted && ioh->fd_read && FD_ISSET(ioh->fd, readfds)) { ioh->fd_read(ioh->opaque); } if (!ioh->deleted && ioh->fd_write && FD_ISSET(ioh->fd, writefds)) { 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-common.h +3 −0 Original line number Diff line number Diff line Loading @@ -227,6 +227,9 @@ typedef void IOReadHandler(void *opaque, const uint8_t *buf, int size); typedef int IOCanReadHandler(void *opaque); typedef 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); struct ParallelIOArg { void *buffer; int count; Loading
vl.c +5 −101 Original line number Diff line number Diff line Loading @@ -1022,68 +1022,6 @@ void pcmcia_info(Monitor *mon) "Empty"); } /***********************************************************/ /* 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); /* 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_handler2(int fd, IOCanReadHandler *fd_read_poll, IOHandler *fd_read, 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; } int qemu_set_fd_handler(int fd, IOHandler *fd_read, IOHandler *fd_write, void *opaque) { return qemu_set_fd_handler2(fd, NULL, fd_read, fd_write, opaque); } /***********************************************************/ /* machine registration */ Loading Loading @@ -1343,7 +1281,6 @@ void qemu_system_vmstop_request(int reason) void main_loop_wait(int nonblocking) { IOHandlerRecord *ioh; fd_set rfds, wfds, xfds; int ret, nfds; struct timeval tv; Loading @@ -1358,56 +1295,23 @@ void main_loop_wait(int nonblocking) os_host_main_loop_wait(&timeout); tv.tv_sec = timeout / 1000; tv.tv_usec = (timeout % 1000) * 1000; /* poll any events */ /* XXX: separate device handlers from system ones */ nfds = -1; 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; } } tv.tv_sec = timeout / 1000; tv.tv_usec = (timeout % 1000) * 1000; qemu_iohandler_fill(&nfds, &rfds, &wfds, &xfds); slirp_select_fill(&nfds, &rfds, &wfds, &xfds); qemu_mutex_unlock_iothread(); 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_iohandler_poll(&rfds, &wfds, &xfds, ret); slirp_select_poll(&rfds, &wfds, &xfds, (ret < 0)); qemu_run_all_timers(); Loading