We need to have a different id for each client, otherwise we get a reference to
other client's cache, and of course we don't sync with the new client.
NOTE: This is quite strange - why are we using a client provided id? only makes 
sense
for migration (it already has cache, we get cache by migration). So right now
we will advance the id if we find it is already there, unless migrate is on, in
which case we do nothing.

At this point connecting multiple clients with display and cursor channels 
works.
previously you could already connect with multiple clients where the second and
more used only the inputs channel.

You can still crash on lack of Drawables or CursorItems due to speed mismatch 
between
the clients (easier to trigger with windows vms).
This will be fixed in later patches by introducing pipe squashing.

FIXME: Note that the current patchset turns on multiclient support 
unconditionaly. This must
be fixed before applying, by adding spice api and using it from qemu (and 
relevant testers
will help too).
---
 server/red_worker.c |   31 +++++++++++++++++++++++++++++++
 1 files changed, 31 insertions(+), 0 deletions(-)

diff --git a/server/red_worker.c b/server/red_worker.c
index 4a546ab..1e6f495 100644
--- a/server/red_worker.c
+++ b/server/red_worker.c
@@ -9343,6 +9343,23 @@ static PixmapCache *red_create_pixmap_cache(uint8_t id, 
int64_t size)
     return cache;
 }
 
+static int red_find_pixmap_cache(uint8_t id)
+{
+    int exists = FALSE;
+    RingItem *now;
+
+    pthread_mutex_lock(&cache_lock);
+    now = &pixmap_cache_list;
+    while ((now = ring_next(&pixmap_cache_list, now))) {
+        if (((PixmapCache *)now)->id == id) {
+            exists = TRUE;
+            break;
+        }
+    }
+    pthread_mutex_unlock(&cache_lock);
+    return exists;
+}
+
 static PixmapCache *red_get_pixmap_cache(uint8_t id, int64_t size)
 {
     PixmapCache *cache = NULL;
@@ -9404,6 +9421,20 @@ static int 
display_channel_init_glz_dictionary(DisplayChannelClient *dcc,
 
 static int display_channel_init(DisplayChannelClient *dcc, 
SpiceMsgcDisplayInit *init_info)
 {
+    // DOCS: MC: we need to have a different id for each client, otherwise we 
get
+    // a reference to other client's cache, and of course we don't sync with 
the new client.
+    // NOTE: this is quite strange - why are we using a client provided id? 
only makes
+    // sense for migration (it already has cache, we get cache by migration).
+    // So right now we will advance the id if we find it is already there, 
unless migrate
+    // is on, in which case we do nothing
+    if (!dcc->common.base.channel->migrate) {
+        while (_red_find_glz_dictionary(init_info->glz_dictionary_id)) {
+            ++init_info->glz_dictionary_id;
+        }
+        while (red_find_pixmap_cache(init_info->pixmap_cache_id)) {
+            ++init_info->pixmap_cache_id;
+        }
+    }
     return (display_channel_init_cache(dcc, init_info) &&
             display_channel_init_glz_dictionary(dcc, init_info));
 }
-- 
1.7.5.1

_______________________________________________
Spice-devel mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/spice-devel

Reply via email to