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