[PATCH spice-server 2/3] stream: implements flush using TCP_CORK

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Cork is a system interface implemented by Linux and some *BSD systems to
tell the system that other data are expected to be written to a socket.
This allows the system to reduce network fragmentation waiting a network
packet to be complete.

Using some replay capture and some instrumentation resulted in a
bandwith reduction of 11% and a packet reduction of 56%.

Signed-off-by: Frediano Ziglio <fziglio@xxxxxxxxxx>
---
 server/red-stream.c | 34 +++++++++++++++++++++++++++++++++-
 1 file changed, 33 insertions(+), 1 deletion(-)

diff --git a/server/red-stream.c b/server/red-stream.c
index 4812d8e4..4833077c 100644
--- a/server/red-stream.c
+++ b/server/red-stream.c
@@ -24,6 +24,7 @@
 #include <unistd.h>
 #include <sys/socket.h>
 #include <fcntl.h>
+#include <netinet/tcp.h>
 
 #include <glib.h>
 
@@ -83,6 +84,8 @@ struct RedStreamPrivate {
      * 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)(RedStream *s, void *buf, size_t nbyte);
     ssize_t (*write)(RedStream *s, const void *buf, size_t nbyte);
@@ -92,6 +95,15 @@ struct RedStreamPrivate {
     SpiceCoreInterfaceInternal *core;
 };
 
+/**
+ * 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(RedStream *s, const void *buf, size_t size)
 {
     return write(s->socket, buf, size);
@@ -205,11 +217,31 @@ bool red_stream_write_all(RedStream *stream, const void *in_buf, size_t n)
 
 bool red_stream_set_auto_flush(RedStream *s, bool enable)
 {
-    return enable;
+    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 red_stream_flush(RedStream *s)
 {
+    if (s->priv->corked) {
+        socket_set_cork(s->socket, 0);
+        socket_set_cork(s->socket, 1);
+    }
 }
 
 #if HAVE_SASL
-- 
2.14.3

_______________________________________________
Spice-devel mailing list
Spice-devel@xxxxxxxxxxxxxxxxxxxxx
https://lists.freedesktop.org/mailman/listinfo/spice-devel




[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux]     [Linux OMAP]     [Linux MIPS]     [ECOS]     [Asterisk Internet PBX]     [Linux API]     [Monitors]