[Spice-devel] [RFCv5 13/47] server/reds: add concept of secondary channels

Alon Levy alevy at redhat.com
Sun May 8 06:11:09 PDT 2011


Secondary channels are those that don't support multiple clients. The
support added in this patch just doesn't let the second or more connected
client receive the unsupported channels in the channels list sent by the
server to the client. This doesn't handle the situation where:

client A connects (gets all channels)
client B connects (gets supported multiple client channels)
client A disconnects (Suboptimal 1: B doesn't get new channels at this point)
client C connects (Suboptimal 2: C doesn't get the full list of channels, but
the partial one)

Specifically the channels that only support a single client are:
 sound (both playback and record channels)
 smartcard
 tunnel
---
 server/reds.c |   30 ++++++++++++++++++++++++++----
 1 files changed, 26 insertions(+), 4 deletions(-)

diff --git a/server/reds.c b/server/reds.c
index 347fa4b..5b1dfd3 100644
--- a/server/reds.c
+++ b/server/reds.c
@@ -1001,18 +1001,40 @@ int reds_num_of_channels()
     return reds ? reds->num_of_channels : 0;
 }
 
+static int secondary_channels[] = {
+    SPICE_CHANNEL_MAIN, SPICE_CHANNEL_DISPLAY, SPICE_CHANNEL_CURSOR, SPICE_CHANNEL_INPUTS};
+
+static int channel_is_secondary(Channel *channel)
+{
+    int i;
+    for (i = 0 ; i < sizeof(secondary_channels)/sizeof(secondary_channels[0]); ++i) {
+        if (channel->type == secondary_channels[i]) {
+            return TRUE;
+        }
+    }
+    return FALSE;
+}
+
 void reds_fill_channels(SpiceMsgChannels *channels_info)
 {
     Channel *channel;
     int i;
+    int used_channels = 0;
 
     channels_info->num_of_channels = reds->num_of_channels;
     channel = reds->channels;
-    for (i = 0; i < reds->num_of_channels; i++) {
+    for (i = 0; i < reds->num_of_channels; i++, channel = channel->next) {
         ASSERT(channel);
-        channels_info->channels[i].type = channel->type;
-        channels_info->channels[i].id = channel->id;
-        channel = channel->next;
+        if (reds->num_clients > 1 && !channel_is_secondary(channel)) {
+            continue;
+        }
+        channels_info->channels[used_channels].type = channel->type;
+        channels_info->channels[used_channels].id = channel->id;
+        used_channels++;
+    }
+    channels_info->num_of_channels = used_channels;
+    if (used_channels != reds->num_of_channels) {
+        red_printf("sent %d out of %d", used_channels, reds->num_of_channels);
     }
 }
 
-- 
1.7.5.1



More information about the Spice-devel mailing list