diff options
-rw-r--r-- | main-loop.c | 69 | ||||
-rw-r--r-- | main-loop.h | 1 | ||||
-rw-r--r-- | oslib-win32.c | 3 |
3 files changed, 48 insertions, 25 deletions
diff --git a/main-loop.c b/main-loop.c index dc6bdb591f..7364074c56 100644 --- a/main-loop.c +++ b/main-loop.c @@ -392,10 +392,18 @@ void qemu_del_wait_object(HANDLE handle, WaitObjectFunc *func, void *opaque) } } +void qemu_fd_register(int fd) +{ + WSAEventSelect(fd, qemu_event_handle, FD_READ | FD_ACCEPT | FD_CLOSE | + FD_CONNECT | FD_WRITE | FD_OOB); +} + static int os_host_main_loop_wait(int timeout) { int ret, ret2, i; PollingEntry *pe; + int err; + WaitObjects *w = &wait_objects; static struct timeval tv0; /* XXX: need to suppress polling by better using win32 events */ @@ -403,38 +411,49 @@ static int os_host_main_loop_wait(int timeout) for (pe = first_polling_entry; pe != NULL; pe = pe->next) { ret |= pe->func(pe->opaque); } - if (ret == 0) { - int err; - WaitObjects *w = &wait_objects; + if (ret != 0) { + return ret; + } - qemu_mutex_unlock_iothread(); - ret = WaitForMultipleObjects(w->num, w->events, FALSE, timeout); - qemu_mutex_lock_iothread(); - if (WAIT_OBJECT_0 + 0 <= ret && ret <= WAIT_OBJECT_0 + w->num - 1) { - if (w->func[ret - WAIT_OBJECT_0]) { - w->func[ret - WAIT_OBJECT_0](w->opaque[ret - WAIT_OBJECT_0]); - } + if (nfds >= 0) { + ret = select(nfds + 1, &rfds, &wfds, &xfds, &tv0); + if (ret != 0) { + timeout = 0; + } + } - /* Check for additional signaled events */ - for (i = (ret - WAIT_OBJECT_0 + 1); i < w->num; i++) { - /* Check if event is signaled */ - ret2 = WaitForSingleObject(w->events[i], 0); - if (ret2 == WAIT_OBJECT_0) { - if (w->func[i]) { - w->func[i](w->opaque[i]); - } - } else if (ret2 != WAIT_TIMEOUT) { - err = GetLastError(); - fprintf(stderr, "WaitForSingleObject error %d %d\n", i, err); + qemu_mutex_unlock_iothread(); + ret = WaitForMultipleObjects(w->num, w->events, FALSE, timeout); + qemu_mutex_lock_iothread(); + if (WAIT_OBJECT_0 + 0 <= ret && ret <= WAIT_OBJECT_0 + w->num - 1) { + if (w->func[ret - WAIT_OBJECT_0]) { + w->func[ret - WAIT_OBJECT_0](w->opaque[ret - WAIT_OBJECT_0]); + } + + /* Check for additional signaled events */ + for (i = (ret - WAIT_OBJECT_0 + 1); i < w->num; i++) { + /* Check if event is signaled */ + ret2 = WaitForSingleObject(w->events[i], 0); + if (ret2 == WAIT_OBJECT_0) { + if (w->func[i]) { + w->func[i](w->opaque[i]); } + } else if (ret2 != WAIT_TIMEOUT) { + err = GetLastError(); + fprintf(stderr, "WaitForSingleObject error %d %d\n", i, err); } - } else if (ret != WAIT_TIMEOUT) { - err = GetLastError(); - fprintf(stderr, "WaitForMultipleObjects error %d %d\n", ret, err); } + } else if (ret != WAIT_TIMEOUT) { + err = GetLastError(); + fprintf(stderr, "WaitForMultipleObjects error %d %d\n", ret, err); } - ret = select(nfds + 1, &rfds, &wfds, &xfds, &tv0); + + /* If an edge-triggered socket event occurred, select will return a + * positive result on the next iteration. We do not need to do anything + * here. + */ + return ret; } #endif diff --git a/main-loop.h b/main-loop.h index 4987041ce7..e743aa0cf6 100644 --- a/main-loop.h +++ b/main-loop.h @@ -359,6 +359,7 @@ void qemu_mutex_unlock_iothread(void); /* internal interfaces */ +void qemu_fd_register(int fd); 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); diff --git a/oslib-win32.c b/oslib-win32.c index ce3021e6c7..ffbc6d0c9f 100644 --- a/oslib-win32.c +++ b/oslib-win32.c @@ -28,6 +28,7 @@ #include <windows.h> #include "config-host.h" #include "sysemu.h" +#include "main-loop.h" #include "trace.h" #include "qemu_socket.h" @@ -76,6 +77,7 @@ void qemu_vfree(void *ptr) void socket_set_block(int fd) { unsigned long opt = 0; + WSAEventSelect(fd, NULL, 0); ioctlsocket(fd, FIONBIO, &opt); } @@ -83,6 +85,7 @@ void socket_set_nonblock(int fd) { unsigned long opt = 1; ioctlsocket(fd, FIONBIO, &opt); + qemu_fd_register(fd); } int inet_aton(const char *cp, struct in_addr *ia) |