summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKevin Wolf2016-11-07 16:34:35 +0100
committerKevin Wolf2017-01-09 13:30:52 +0100
commit536fca7f7ea4913f71df7f420953e97619be74e1 (patch)
treea23646c39583a7a43ced78c5714b5103f5aa7fce
parentqemu-img: fix in-flight count for qemu-img bench (diff)
downloadqemu-536fca7f7ea4913f71df7f420953e97619be74e1.tar.gz
qemu-536fca7f7ea4913f71df7f420953e97619be74e1.tar.xz
qemu-536fca7f7ea4913f71df7f420953e97619be74e1.zip
coroutine: Introduce qemu_coroutine_enter_if_inactive()
In the context of asynchronous work, if we have a worker coroutine that didn't yield, the parent coroutine cannot be reentered because it hasn't yielded yet. In this case we don't even have to reenter the parent because it will see that the work is already done and won't even yield. Signed-off-by: Kevin Wolf <kwolf@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> Reviewed-by: Alberto Garcia <berto@igalia.com>
-rw-r--r--include/qemu/coroutine.h6
-rw-r--r--util/qemu-coroutine.c7
2 files changed, 13 insertions, 0 deletions
diff --git a/include/qemu/coroutine.h b/include/qemu/coroutine.h
index e6a60d55fd..12584ed1b7 100644
--- a/include/qemu/coroutine.h
+++ b/include/qemu/coroutine.h
@@ -71,6 +71,12 @@ Coroutine *qemu_coroutine_create(CoroutineEntry *entry, void *opaque);
void qemu_coroutine_enter(Coroutine *coroutine);
/**
+ * Transfer control to a coroutine if it's not active (i.e. part of the call
+ * stack of the running coroutine). Otherwise, do nothing.
+ */
+void qemu_coroutine_enter_if_inactive(Coroutine *co);
+
+/**
* Transfer control back to a coroutine's caller
*
* This function does not return until the coroutine is re-entered using
diff --git a/util/qemu-coroutine.c b/util/qemu-coroutine.c
index 737bffa984..a5d2f6c0c3 100644
--- a/util/qemu-coroutine.c
+++ b/util/qemu-coroutine.c
@@ -131,6 +131,13 @@ void qemu_coroutine_enter(Coroutine *co)
}
}
+void qemu_coroutine_enter_if_inactive(Coroutine *co)
+{
+ if (!qemu_coroutine_entered(co)) {
+ qemu_coroutine_enter(co);
+ }
+}
+
void coroutine_fn qemu_coroutine_yield(void)
{
Coroutine *self = qemu_coroutine_self();