[Spice-devel] [PATCH 6/7] Respect IOV_MAX if defined

Dan McGee dpmcgee at gmail.com
Thu Feb 16 21:30:12 PST 2012


Solaris has a pitiful maximum writev vector size of only 16, so the ping
request at initial startup destroyed this call and broke things
immediately. Reimplement stream_writev_cb() to respect IOV_MAX and break
the writev() calls into chunks as necessary. Care was taken to return
the correct values as necessary so the EAGAIN handling logic can
determine where to resume the writev call the next time around.

Signed-off-by: Dan McGee <dpmcgee at gmail.com>
---
 server/reds.c |   27 ++++++++++++++++++++++++++-
 1 files changed, 26 insertions(+), 1 deletions(-)

diff --git a/server/reds.c b/server/reds.c
index 250e0ca..797d9d5 100644
--- a/server/reds.c
+++ b/server/reds.c
@@ -23,6 +23,7 @@
 #include <stdio.h>
 #include <unistd.h>
 #include <sys/socket.h>
+#include <sys/uio.h>
 #include <netinet/in.h>
 #include <netinet/tcp.h>
 #include <arpa/inet.h>
@@ -340,7 +341,31 @@ static ssize_t stream_write_cb(RedsStream *s, const void *buf, size_t size)
 
 static ssize_t stream_writev_cb(RedsStream *s, const struct iovec *iov, int iovcnt)
 {
-    return writev(s->socket, iov, iovcnt);
+    ssize_t ret = 0;
+    do {
+        int tosend;
+        ssize_t n, expected = 0;
+        int i;
+#ifdef IOV_MAX
+        tosend = MIN(iovcnt, IOV_MAX);
+#else
+        tosend = iovcnt;
+#endif
+        for (i = 0; i < tosend; i++) {
+            expected += iov[i].iov_len;
+        }
+        n = writev(s->socket, iov, tosend);
+        if (n <= expected) {
+            if (n > 0)
+                ret += n;
+            return ret == 0 ? n : ret;
+        }
+        ret += n;
+        iov += tosend;
+        iovcnt -= tosend;
+    } while(iovcnt > 0);
+
+    return ret;
 }
 
 static ssize_t stream_read_cb(RedsStream *s, void *buf, size_t size)
-- 
1.7.9.1



More information about the Spice-devel mailing list