Use a pipe to signal pending work for the iothread. Signed-off-by: Marcelo Tosatti Index: trunk/qemu-common.h =================================================================== --- trunk.orig/qemu-common.h +++ trunk/qemu-common.h @@ -186,6 +186,8 @@ int cpu_load(QEMUFile *f, void *opaque, /* Force QEMU to stop what it's doing and service IO */ void qemu_service_io(void); +void main_loop_break(void); + /* Force QEMU to process pending events */ void qemu_notify_event(void); Index: trunk/vl.c =================================================================== --- trunk.orig/vl.c +++ trunk/vl.c @@ -275,6 +275,8 @@ static QEMUTimer *nographic_timer; uint8_t qemu_uuid[16]; +static int io_thread_fd = -1; + /***********************************************************/ /* x86 ISA bus support */ @@ -3631,6 +3633,55 @@ void qemu_notify_event(void) } } +void main_loop_break(void) +{ + uint64_t value = 1; + char buffer[8]; + size_t offset = 0; + + if (io_thread_fd == -1) + return; + + memcpy(buffer, &value, sizeof(value)); + + while (offset < 8) { + ssize_t len; + + len = write(io_thread_fd, buffer + offset, 8 - offset); + if (len == -1 && errno == EINTR) + continue; + + if (len <= 0) + break; + + offset += len; + } + + if (offset != 8) + fprintf(stderr, "failed to notify io thread\n"); +} + +/* Used to break IO thread out of select */ +static void io_thread_wakeup(void *opaque) +{ + int fd = (unsigned long)opaque; + char buffer[8]; + size_t offset = 0; + + while (offset < 8) { + ssize_t len; + + len = read(fd, buffer + offset, 8 - offset); + if (len == -1 && errno == EINTR) + continue; + + if (len <= 0) + break; + + offset += len; + } +} + #ifdef _WIN32 static void host_main_loop_wait(int *timeout) { @@ -3773,6 +3824,20 @@ void main_loop_wait(int timeout) } +static void setup_iothread_fd(void) +{ + int fds[2]; + + if (pipe(fds) == -1) { + fprintf(stderr, "failed to create iothread pipe"); + exit(0); + } + + qemu_set_fd_handler2(fds[0], NULL, io_thread_wakeup, NULL, + (void *)(unsigned long)fds[0]); + io_thread_fd = fds[1]; +} + static int main_loop(void) { int ret, timeout;