[Spice-devel] [PATCH spice-server 3/3] worker: use manual flushing on stream to decrease packet fragmentation

Frediano Ziglio fziglio at redhat.com
Fri Feb 10 12:10:56 UTC 2017


Signed-off-by: Frediano Ziglio <fziglio at redhat.com>
---
 server/common-graphics-channel.c | 26 +++++++++++++++-----------
 server/red-channel-client.c      | 16 ++++++++++------
 2 files changed, 25 insertions(+), 17 deletions(-)

diff --git a/server/common-graphics-channel.c b/server/common-graphics-channel.c
index 29aa583..3e40b45 100644
--- a/server/common-graphics-channel.c
+++ b/server/common-graphics-channel.c
@@ -26,6 +26,8 @@
 #include "common-graphics-channel.h"
 #include "dcc.h"
 #include "red-client.h"
+#include "main-channel-client.h"
+#include "red-channel-client-private.h"
 
 #define CHANNEL_RECEIVE_BUF_SIZE 1024
 
@@ -133,17 +135,19 @@ int common_channel_config_socket(RedChannelClient *rcc)
 
     // TODO - this should be dynamic, not one time at channel creation
     is_low_bandwidth = main_channel_client_is_low_bandwidth(mcc);
-    delay_val = is_low_bandwidth ? 0 : 1;
-    /* FIXME: Using Nagle's Algorithm can lead to apparent delays, depending
-     * on the delayed ack timeout on the other side.
-     * Instead of using Nagle's, we need to implement message buffering on
-     * the application level.
-     * see: http://www.stuartcheshire.org/papers/NagleDelayedAck/
-     */
-    if (setsockopt(stream->socket, IPPROTO_TCP, TCP_NODELAY, &delay_val,
-                   sizeof(delay_val)) == -1) {
-        if (errno != ENOTSUP) {
-            spice_warning("setsockopt failed, %s", strerror(errno));
+    if (!reds_stream_set_auto_flush(rcc->priv->stream, false)) {
+        delay_val = is_low_bandwidth ? 0 : 1;
+        /* FIXME: Using Nagle's Algorithm can lead to apparent delays, depending
+         * on the delayed ack timeout on the other side.
+         * Instead of using Nagle's, we need to implement message buffering on
+         * the application level.
+         * see: http://www.stuartcheshire.org/papers/NagleDelayedAck/
+         */
+        if (setsockopt(stream->socket, IPPROTO_TCP, TCP_NODELAY, &delay_val,
+                       sizeof(delay_val)) == -1) {
+            if (errno != ENOTSUP) {
+                spice_warning("setsockopt failed, %s", strerror(errno));
+            }
         }
     }
     // TODO: move wide/narrow ack setting to red_channel.
diff --git a/server/red-channel-client.c b/server/red-channel-client.c
index 0002951..90ce730 100644
--- a/server/red-channel-client.c
+++ b/server/red-channel-client.c
@@ -1220,12 +1220,16 @@ void red_channel_client_push(RedChannelClient *rcc)
     while ((pipe_item = red_channel_client_pipe_item_get(rcc))) {
         red_channel_client_send_item(rcc, pipe_item);
     }
-    if (red_channel_client_no_item_being_sent(rcc) && g_queue_is_empty(&rcc->priv->pipe)
-        && rcc->priv->stream->watch) {
-        SpiceCoreInterfaceInternal *core;
-        core = red_channel_get_core_interface(rcc->priv->channel);
-        core->watch_update_mask(core, rcc->priv->stream->watch,
-                                SPICE_WATCH_EVENT_READ);
+    if (red_channel_client_no_item_being_sent(rcc) && g_queue_is_empty(&rcc->priv->pipe)) {
+        if (rcc->priv->stream->watch) {
+            SpiceCoreInterfaceInternal *core;
+            core = red_channel_get_core_interface(rcc->priv->channel);
+            core->watch_update_mask(core, rcc->priv->stream->watch,
+                                    SPICE_WATCH_EVENT_READ);
+        }
+        reds_stream_flush(rcc->priv->stream);
+    } else if (red_channel_client_waiting_for_ack(rcc)) {
+        reds_stream_flush(rcc->priv->stream);
     }
     rcc->priv->during_send = FALSE;
     g_object_unref(rcc);
-- 
2.9.3



More information about the Spice-devel mailing list