[libvirt] [PATCH 19/27] virStreamSendAll: Wire up sparse streams

Michal Privoznik mprivozn at redhat.com
Thu Apr 28 10:05:06 UTC 2016


Plenty of clients use virStreamSendAll() instead of using
virStreamSend() directly. We should allow those clients to
utilize the new feature too.

Signed-off-by: Michal Privoznik <mprivozn at redhat.com>
---
 src/libvirt-stream.c | 37 +++++++++++++++++++++++++++++++------
 1 file changed, 31 insertions(+), 6 deletions(-)

diff --git a/src/libvirt-stream.c b/src/libvirt-stream.c
index 371efed..989c0b2 100644
--- a/src/libvirt-stream.c
+++ b/src/libvirt-stream.c
@@ -528,9 +528,10 @@ virStreamSendAll(virStreamPtr stream,
                  virStreamSourceFunc handler,
                  void *opaque)
 {
-    char *bytes = NULL;
-    size_t want = VIR_NET_MESSAGE_LEGACY_PAYLOAD_MAX;
+    char *buf = NULL;
+    size_t bufSize = VIR_NET_MESSAGE_LEGACY_PAYLOAD_MAX;
     int ret = -1;
+    unsigned long long dataLen = 0;
     VIR_DEBUG("stream=%p, handler=%p, opaque=%p", stream, handler, opaque);
 
     virResetLastError();
@@ -544,12 +545,35 @@ virStreamSendAll(virStreamPtr stream,
         goto cleanup;
     }
 
-    if (VIR_ALLOC_N(bytes, want) < 0)
+    if (VIR_ALLOC_N(buf, bufSize) < 0)
         goto cleanup;
 
     for (;;) {
+        size_t want = bufSize;
         int got, offset = 0;
-        got = (handler)(stream, bytes, want, opaque);
+
+        if (stream->inDataCb && !dataLen) {
+            int inData = 0;
+            int rv = virStreamInData(stream, &inData, &dataLen);
+
+            if (rv < 0) {
+                virStreamAbort(stream);
+                goto cleanup;
+            }
+
+            if (!inData && dataLen) {
+                if (virStreamSkip(stream, dataLen) < 0 ||
+                    virStreamSkipCallback(stream, dataLen) < 0) {
+                    virStreamAbort(stream);
+                    goto cleanup;
+                }
+            }
+        }
+
+        if (dataLen && want > dataLen)
+            want = dataLen;
+
+        got = (handler)(stream, buf, want, opaque);
         if (got < 0) {
             virStreamAbort(stream);
             goto cleanup;
@@ -558,16 +582,17 @@ virStreamSendAll(virStreamPtr stream,
             break;
         while (offset < got) {
             int done;
-            done = virStreamSend(stream, bytes + offset, got - offset);
+            done = virStreamSend(stream, buf + offset, got - offset);
             if (done < 0)
                 goto cleanup;
             offset += done;
+            dataLen -= done;
         }
     }
     ret = 0;
 
  cleanup:
-    VIR_FREE(bytes);
+    VIR_FREE(buf);
 
     if (ret != 0)
         virDispatchError(stream->conn);
-- 
2.8.1




More information about the libvir-list mailing list