diff options
author | Peter Maydell | 2019-07-16 16:08:29 +0200 |
---|---|---|
committer | Peter Maydell | 2019-07-16 16:08:29 +0200 |
commit | 697f59243f5a28b8a243ff5ad59e34bbecffcae1 (patch) | |
tree | 2fc3d16a3c39aa3576cc7fd65a208a43ad6e5e92 /util/main-loop.c | |
parent | Merge remote-tracking branch 'remotes/armbru/tags/pull-build-2019-07-15' into... (diff) | |
parent | vl: make sure char-pty message displayed by moving setbuf to the beginning (diff) | |
download | qemu-697f59243f5a28b8a243ff5ad59e34bbecffcae1.tar.gz qemu-697f59243f5a28b8a243ff5ad59e34bbecffcae1.tar.xz qemu-697f59243f5a28b8a243ff5ad59e34bbecffcae1.zip |
Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging
* VFIO bugfix for AMD SEV (Alex)
* Kconfig improvements (Julio, Philippe)
* MemoryRegion reference counting bugfix (King Wang)
* Build system cleanups (Marc-André, myself)
* rdmacm-mux off-by-one (Marc-André)
* ZBC passthrough fixes (Shinichiro, myself)
* WHPX build fix (Stefan)
* char-pty fix (Wei Yang)
# gpg: Signature made Tue 16 Jul 2019 08:31:27 BST
# gpg: using RSA key BFFBD25F78C7AE83
# gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>" [full]
# gpg: aka "Paolo Bonzini <pbonzini@redhat.com>" [full]
# Primary key fingerprint: 46F5 9FBD 57D6 12E7 BFD4 E2F7 7E15 100C CD36 69B1
# Subkey fingerprint: F133 3857 4B66 2389 866C 7682 BFFB D25F 78C7 AE83
* remotes/bonzini/tags/for-upstream:
vl: make sure char-pty message displayed by moving setbuf to the beginning
create_config: remove $(CONFIG_SOFTMMU) hack
Makefile: do not repeat $(CONFIG_SOFTMMU) in hw/Makefile.objs
hw/usb/Kconfig: USB_XHCI_NEC requires USB_XHCI
hw/usb/Kconfig: Add CONFIG_USB_EHCI_PCI
target/i386: sev: Do not unpin ram device memory region
checkpatch: detect doubly-encoded UTF-8
hw/lm32/Kconfig: Milkymist One provides a USB 1.1 Controller
util: merge main-loop.c and iohandler.c
Fix broken build with WHPX enabled
memory: unref the memory region in simplify flatview
hw/i386: turn off vmport if CONFIG_VMPORT is disabled
rdmacm-mux: fix strcpy string warning
build-sys: remove slirp cflags from main-loop.o
iscsi: base all handling of check condition on scsi_sense_to_errno
iscsi: fix busy/timeout/task set full
scsi: add guest-recoverable ZBC errors
scsi: explicitly list guest-recoverable sense codes
scsi-disk: pass sense correctly for guest-recoverable errors
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'util/main-loop.c')
-rw-r--r-- | util/main-loop.c | 110 |
1 files changed, 110 insertions, 0 deletions
diff --git a/util/main-loop.c b/util/main-loop.c index a9f4e8de75..e3eaa55866 100644 --- a/util/main-loop.c +++ b/util/main-loop.c @@ -32,6 +32,11 @@ #include "qemu/main-loop.h" #include "block/aio.h" #include "qemu/error-report.h" +#include "qemu/queue.h" + +#ifndef _WIN32 +#include <sys/wait.h> +#endif #ifndef _WIN32 @@ -525,3 +530,108 @@ QEMUBH *qemu_bh_new(QEMUBHFunc *cb, void *opaque) { return aio_bh_new(qemu_aio_context, cb, opaque); } + +/* + * Functions to operate on the I/O handler AioContext. + * This context runs on top of main loop. We can't reuse qemu_aio_context + * because iohandlers mustn't be polled by aio_poll(qemu_aio_context). + */ +static AioContext *iohandler_ctx; + +static void iohandler_init(void) +{ + if (!iohandler_ctx) { + iohandler_ctx = aio_context_new(&error_abort); + } +} + +AioContext *iohandler_get_aio_context(void) +{ + iohandler_init(); + return iohandler_ctx; +} + +GSource *iohandler_get_g_source(void) +{ + iohandler_init(); + return aio_get_g_source(iohandler_ctx); +} + +void qemu_set_fd_handler(int fd, + IOHandler *fd_read, + IOHandler *fd_write, + void *opaque) +{ + iohandler_init(); + aio_set_fd_handler(iohandler_ctx, fd, false, + fd_read, fd_write, NULL, opaque); +} + +void event_notifier_set_handler(EventNotifier *e, + EventNotifierHandler *handler) +{ + iohandler_init(); + aio_set_event_notifier(iohandler_ctx, e, false, + handler, NULL); +} + +/* reaping of zombies. right now we're not passing the status to + anyone, but it would be possible to add a callback. */ +#ifndef _WIN32 +typedef struct ChildProcessRecord { + int pid; + QLIST_ENTRY(ChildProcessRecord) next; +} ChildProcessRecord; + +static QLIST_HEAD(, ChildProcessRecord) child_watches = + QLIST_HEAD_INITIALIZER(child_watches); + +static QEMUBH *sigchld_bh; + +static void sigchld_handler(int signal) +{ + qemu_bh_schedule(sigchld_bh); +} + +static void sigchld_bh_handler(void *opaque) +{ + ChildProcessRecord *rec, *next; + + QLIST_FOREACH_SAFE(rec, &child_watches, next, next) { + if (waitpid(rec->pid, NULL, WNOHANG) == rec->pid) { + QLIST_REMOVE(rec, next); + g_free(rec); + } + } +} + +static void qemu_init_child_watch(void) +{ + struct sigaction act; + sigchld_bh = qemu_bh_new(sigchld_bh_handler, NULL); + + memset(&act, 0, sizeof(act)); + act.sa_handler = sigchld_handler; + act.sa_flags = SA_NOCLDSTOP; + sigaction(SIGCHLD, &act, NULL); +} + +int qemu_add_child_watch(pid_t pid) +{ + ChildProcessRecord *rec; + + if (!sigchld_bh) { + qemu_init_child_watch(); + } + + QLIST_FOREACH(rec, &child_watches, next) { + if (rec->pid == pid) { + return 1; + } + } + rec = g_malloc0(sizeof(ChildProcessRecord)); + rec->pid = pid; + QLIST_INSERT_HEAD(&child_watches, rec, next); + return 0; +} +#endif |