[Spice-commits] Branch '0.10' - server/red_channel.c server/red_channel.h server/spicevmc.c

Hans de Goede jwrdegoede at kemper.freedesktop.org
Mon Feb 20 07:35:57 PST 2012

 server/red_channel.c |    2 ++
 server/red_channel.h |    1 +
 server/spicevmc.c    |    6 +++---
 3 files changed, 6 insertions(+), 3 deletions(-)

New commits:
commit 83d000fdab9666a328e38f0552b749fcde545ad0
Author: Hans de Goede <hdegoede at redhat.com>
Date:   Wed Feb 8 10:04:18 2012 +0100

    server/spicevmc: Don't destroy the rcc twice
    spicevmc calls red_channel_client_destroy() on the rcc when it disconnects
    since we don't want to delay the destroy until the session gets closed as
    spicevmc channels can be opened, closed and opened again during a single
    This causes red_channel_client_destroy() to get called twice, triggering
    an assert, when a connected channel gets destroyed.
    This was fixed with commit ffc4de01e6f9ea0676f17b10e45a137d7e15d6ac for
    the case where: a spicevmc channel was open on client disconnected, and
    the main channel disconnect gets handled first.
    But the channel can also be destroyed when the chardev gets unregistered
    with the spice-server. This path still triggers the assert.
    This patch fixes this by adding a destroying flag to the rcc struct, and
    also moves the previous fix over to the same, more clean, method of
    detecting this special case.
    Signed-off-by: Hans de Goede <hdegoede at redhat.com>

diff --git a/server/red_channel.c b/server/red_channel.c
index ec02018..6296dc9 100644
--- a/server/red_channel.c
+++ b/server/red_channel.c
@@ -780,6 +780,7 @@ void red_channel_set_data(RedChannel *channel, void *data)
 void red_channel_client_destroy(RedChannelClient *rcc)
+    rcc->destroying = 1;
     if (red_channel_client_is_connected(rcc)) {
@@ -1439,6 +1440,7 @@ void red_client_destroy(RedClient *client)
         // some channels may be in other threads, so disconnection
         // is not synchronous.
         rcc = SPICE_CONTAINEROF(link, RedChannelClient, client_link);
+        rcc->destroying = 1;
         // some channels may be in other threads. However we currently
         // assume disconnect is synchronous (we changed the dispatcher
         // to wait for disconnection)
diff --git a/server/red_channel.h b/server/red_channel.h
index 045bfd4..543aec1 100644
--- a/server/red_channel.h
+++ b/server/red_channel.h
@@ -255,6 +255,7 @@ struct RedChannelClient {
     RedChannelCapabilities remote_caps;
     int is_mini_header;
+    int destroying;
 struct RedChannel {
diff --git a/server/spicevmc.c b/server/spicevmc.c
index 5cdc513..30aaf2f 100644
--- a/server/spicevmc.c
+++ b/server/spicevmc.c
@@ -116,9 +116,9 @@ static void spicevmc_red_channel_client_on_disconnect(RedChannelClient *rcc)
     sin = state->chardev_sin;
     sif = SPICE_CONTAINEROF(sin->base.sif, SpiceCharDeviceInterface, base);
-    /* Don't destroy the rcc if the entire client is disconnecting, as then
-       red_client_destroy will already do this! */
-    if (!rcc->client->disconnecting)
+    /* Don't destroy the rcc if it is already being destroyed, as then
+       red_client_destroy/red_channel_client_destroy will already do this! */
+    if (!rcc->destroying)
     state->rcc = NULL;

More information about the Spice-commits mailing list