[Spice-devel] [RFC PATCH 2/3] stream: implements flush using TCP_CORK

Frediano Ziglio fziglio at redhat.com
Tue Feb 16 15:36:26 UTC 2016


Signed-off-by: Frediano Ziglio <fziglio at redhat.com>
---
 server/reds-stream.c | 34 +++++++++++++++++++++++++++++++++-
 1 file changed, 33 insertions(+), 1 deletion(-)

diff --git a/server/reds-stream.c b/server/reds-stream.c
index b630e12..72a870f 100644
--- a/server/reds-stream.c
+++ b/server/reds-stream.c
@@ -30,6 +30,7 @@
 #include <unistd.h>
 #include <sys/socket.h>
 #include <fcntl.h>
+#include <netinet/tcp.h>
 
 #include <glib.h>
 
@@ -90,6 +91,8 @@ struct RedsStreamPrivate {
      * deallocated when main_dispatcher handles the SPICE_CHANNEL_EVENT_DISCONNECTED
      * event, either from same thread or by call back from main thread. */
     SpiceChannelEventInfo* info;
+    bool use_cork;
+    bool corked;
 
     ssize_t (*read)(RedsStream *s, void *buf, size_t nbyte);
     ssize_t (*write)(RedsStream *s, const void *buf, size_t nbyte);
@@ -98,6 +101,15 @@ struct RedsStreamPrivate {
     RedsState *reds;
 };
 
+/**
+ * Set TCP_CORK on socket
+ */
+/* NOTE: enabled must be int */
+static inline int socket_set_cork(int socket, int enabled)
+{
+    return setsockopt(socket, IPPROTO_TCP, TCP_CORK, &enabled, sizeof(enabled));
+}
+
 static ssize_t stream_write_cb(RedsStream *s, const void *buf, size_t size)
 {
     return write(s->socket, buf, size);
@@ -211,11 +223,31 @@ bool reds_stream_write_all(RedsStream *stream, const void *in_buf, size_t n)
 
 bool reds_stream_set_auto_flush(RedsStream *s, bool enable)
 {
-    return false;
+    if (s->priv->use_cork == !enable) {
+        return true;
+    }
+
+    s->priv->use_cork = !enable;
+    if (s->priv->use_cork) {
+        if (socket_set_cork(s->socket, 1)) {
+            s->priv->use_cork = false;
+            return false;
+        } else {
+            s->priv->corked = true;
+        }
+    } else if (s->priv->corked) {
+        socket_set_cork(s->socket, 0);
+        s->priv->corked = false;
+    }
+    return true;
 }
 
 void reds_stream_flush(RedsStream *s)
 {
+    if (s->priv->corked) {
+        socket_set_cork(s->socket, 0);
+        socket_set_cork(s->socket, 1);
+    }
 }
 
 #if HAVE_SASL
-- 
2.5.0



More information about the Spice-devel mailing list