summaryrefslogtreecommitdiffstats
path: root/util/main-loop.c
diff options
context:
space:
mode:
authorPeter Maydell2019-07-16 16:08:29 +0200
committerPeter Maydell2019-07-16 16:08:29 +0200
commit697f59243f5a28b8a243ff5ad59e34bbecffcae1 (patch)
tree2fc3d16a3c39aa3576cc7fd65a208a43ad6e5e92 /util/main-loop.c
parentMerge remote-tracking branch 'remotes/armbru/tags/pull-build-2019-07-15' into... (diff)
parentvl: make sure char-pty message displayed by moving setbuf to the beginning (diff)
downloadqemu-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.c110
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