Blame 0002-io-Yield-rather-than-wait-when-already-in-coroutine.patch

Paolo Bonzini 0fb2b2
From: Eric Blake <eblake@redhat.com>
Paolo Bonzini 0fb2b2
Date: Tue, 5 Sep 2017 14:11:12 -0500
59eb7a
Subject: [PATCH] io: Yield rather than wait when already in coroutine
Paolo Bonzini 0fb2b2
Paolo Bonzini 0fb2b2
The new qio_channel_{read,write}{,v}_all functions are documented
Paolo Bonzini 0fb2b2
as yielding until data is available.  When used on a blocking
Paolo Bonzini 0fb2b2
channel, this yield is done via qio_channel_wait() which spawns
Paolo Bonzini 0fb2b2
a nested event loop under the hood (so it is that secondary loop
Paolo Bonzini 0fb2b2
which yields as needed); but if we are already in a coroutine (at
Paolo Bonzini 0fb2b2
which point QIO_CHANNEL_ERR_BLOCK is only possible if we are a
Paolo Bonzini 0fb2b2
non-blocking channel), we want to yield the current coroutine
Paolo Bonzini 0fb2b2
instead of spawning a nested event loop.
Paolo Bonzini 0fb2b2
Paolo Bonzini 0fb2b2
Signed-off-by: Eric Blake <eblake@redhat.com>
Paolo Bonzini 0fb2b2
Message-Id: <20170905191114.5959-2-eblake@redhat.com>
Paolo Bonzini 0fb2b2
Acked-by: Daniel P. Berrange <berrange@redhat.com>
Paolo Bonzini 0fb2b2
[commit message updated]
Paolo Bonzini 0fb2b2
Signed-off-by: Eric Blake <eblake@redhat.com>
Paolo Bonzini 0fb2b2
---
Paolo Bonzini 0fb2b2
 io/channel.c | 12 ++++++++++--
Paolo Bonzini 0fb2b2
 1 file changed, 10 insertions(+), 2 deletions(-)
Paolo Bonzini 0fb2b2
Paolo Bonzini 0fb2b2
diff --git a/io/channel.c b/io/channel.c
Paolo Bonzini 0fb2b2
index 5e8c2f0a91..9e62794cab 100644
Paolo Bonzini 0fb2b2
--- a/io/channel.c
Paolo Bonzini 0fb2b2
+++ b/io/channel.c
Paolo Bonzini 0fb2b2
@@ -105,7 +105,11 @@ int qio_channel_readv_all(QIOChannel *ioc,
Paolo Bonzini 0fb2b2
         ssize_t len;
Paolo Bonzini 0fb2b2
         len = qio_channel_readv(ioc, local_iov, nlocal_iov, errp);
Paolo Bonzini 0fb2b2
         if (len == QIO_CHANNEL_ERR_BLOCK) {
Paolo Bonzini 0fb2b2
-            qio_channel_wait(ioc, G_IO_IN);
Paolo Bonzini 0fb2b2
+            if (qemu_in_coroutine()) {
Paolo Bonzini 0fb2b2
+                qio_channel_yield(ioc, G_IO_IN);
Paolo Bonzini 0fb2b2
+            } else {
Paolo Bonzini 0fb2b2
+                qio_channel_wait(ioc, G_IO_IN);
Paolo Bonzini 0fb2b2
+            }
Paolo Bonzini 0fb2b2
             continue;
Paolo Bonzini 0fb2b2
         } else if (len < 0) {
Paolo Bonzini 0fb2b2
             goto cleanup;
Paolo Bonzini 0fb2b2
@@ -143,7 +147,11 @@ int qio_channel_writev_all(QIOChannel *ioc,
Paolo Bonzini 0fb2b2
         ssize_t len;
Paolo Bonzini 0fb2b2
         len = qio_channel_writev(ioc, local_iov, nlocal_iov, errp);
Paolo Bonzini 0fb2b2
         if (len == QIO_CHANNEL_ERR_BLOCK) {
Paolo Bonzini 0fb2b2
-            qio_channel_wait(ioc, G_IO_OUT);
Paolo Bonzini 0fb2b2
+            if (qemu_in_coroutine()) {
Paolo Bonzini 0fb2b2
+                qio_channel_yield(ioc, G_IO_OUT);
Paolo Bonzini 0fb2b2
+            } else {
Paolo Bonzini 0fb2b2
+                qio_channel_wait(ioc, G_IO_OUT);
Paolo Bonzini 0fb2b2
+            }
Paolo Bonzini 0fb2b2
             continue;
Paolo Bonzini 0fb2b2
         }
Paolo Bonzini 0fb2b2
         if (len < 0) {