[Spice-devel] [RFC v4 61/62] server/red_worker: give each client a different id for caches

Alon Levy alevy at redhat.com
Tue Apr 26 03:55:26 PDT 2011


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 d1039a2..3e1a56a 100644
--- a/server/red_worker.c
+++ b/server/red_worker.c
@@ -9323,6 +9323,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;
@@ -9384,6 +9401,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.4.4



More information about the Spice-devel mailing list