[spice PATCH 46/55] red_channel (dummy): fix not adding dummy RedChannelClient to the client

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



snd channel wasn't added to be part of the client's channels list.
As a result, when the client was destroyed, or migrated, snd channel
client wasn't destroy, or its migration callback wasn't called.

However, due to adding dummy channels to the client, we need special
handling for calls to disconnecting dummy channel clients.

TODO: we need to refactor snd_worker to use red_channel
---
 server/red_channel.c |   34 +++++++++++++++++++++++-----------
 server/red_channel.h |    4 ++--
 server/snd_worker.c  |    2 +-
 3 files changed, 26 insertions(+), 14 deletions(-)

diff --git a/server/red_channel.c b/server/red_channel.c
index 803804e..18b69d3 100644
--- a/server/red_channel.c
+++ b/server/red_channel.c
@@ -998,9 +998,7 @@ static void red_channel_client_unref(RedChannelClient *rcc)
 void red_channel_client_destroy(RedChannelClient *rcc)
 {
     rcc->destroying = 1;
-    if (red_channel_client_is_connected(rcc)) {
-        red_channel_client_disconnect(rcc);
-    }
+    red_channel_client_disconnect(rcc);
     red_client_remove_channel(rcc);
     red_channel_client_unref(rcc);
 }
@@ -1370,7 +1368,11 @@ void red_channel_pipes_add_empty_msg(RedChannel *channel, int msg_type)
 
 int red_channel_client_is_connected(RedChannelClient *rcc)
 {
-    return rcc->stream != NULL;
+    if (!rcc->dummy) {
+        return rcc->stream != NULL;
+    } else {
+        return rcc->dummy_connected;
+    }
 }
 
 int red_channel_is_connected(RedChannel *channel)
@@ -1429,10 +1431,23 @@ static void red_client_remove_channel(RedChannelClient *rcc)
     pthread_mutex_unlock(&rcc->client->lock);
 }
 
+static void red_channel_client_disconnect_dummy(RedChannelClient *rcc)
+{
+    spice_assert(rcc->dummy);
+    if (ring_item_is_linked(&rcc->channel_link)) {
+        red_channel_remove_client(rcc);
+    }
+    rcc->dummy_connected = FALSE;
+}
+
 void red_channel_client_disconnect(RedChannelClient *rcc)
 {
     spice_printerr("%p (channel %p type %d id %d)", rcc, rcc->channel,
                                                 rcc->channel->type, rcc->channel->id);
+    if (rcc->dummy) {
+        red_channel_client_disconnect_dummy(rcc);
+        return;
+    }
     if (!red_channel_client_is_connected(rcc)) {
         return;
     }
@@ -1490,8 +1505,12 @@ RedChannelClient *red_channel_client_create_dummy(int size,
 
     rcc->incoming.header.data = rcc->incoming.header_buf;
     rcc->incoming.serial = 1;
+    ring_init(&rcc->pipe);
 
+    rcc->dummy = TRUE;
+    rcc->dummy_connected = TRUE;
     red_channel_add_client(channel, rcc);
+    red_client_add_channel(client, rcc);
     pthread_mutex_unlock(&client->lock);
     return rcc;
 error:
@@ -1499,13 +1518,6 @@ error:
     return NULL;
 }
 
-void red_channel_client_destroy_dummy(RedChannelClient *rcc)
-{
-    red_channel_remove_client(rcc);
-    red_channel_client_destroy_remote_caps(rcc);
-    free(rcc);
-}
-
 void red_channel_apply_clients(RedChannel *channel, channel_client_callback cb)
 {
     RingItem *link;
diff --git a/server/red_channel.h b/server/red_channel.h
index de72fff..aab7d2d 100644
--- a/server/red_channel.h
+++ b/server/red_channel.h
@@ -228,6 +228,8 @@ struct RedChannelClient {
     RedChannel *channel;
     RedClient  *client;
     RedsStream *stream;
+    int dummy;
+    int dummy_connected;
 
     uint32_t refs;
 
@@ -353,8 +355,6 @@ RedChannelClient *red_channel_client_create_dummy(int size,
                                                   RedClient  *client,
                                                   int num_common_caps, uint32_t *common_caps,
                                                   int num_caps, uint32_t *caps);
-void red_channel_client_destroy_dummy(RedChannelClient *rcc);
-
 
 int red_channel_is_connected(RedChannel *channel);
 int red_channel_client_is_connected(RedChannelClient *rcc);
diff --git a/server/snd_worker.c b/server/snd_worker.c
index 3599c6f..2746940 100644
--- a/server/snd_worker.c
+++ b/server/snd_worker.c
@@ -223,7 +223,7 @@ static void snd_disconnect_channel(SndChannel *channel)
     }
     channel->cleanup(channel);
     worker = channel->worker;
-    red_channel_client_destroy_dummy(worker->connection->channel_client);
+    red_channel_client_disconnect(worker->connection->channel_client);
     core->watch_remove(channel->stream->watch);
     channel->stream->watch = NULL;
     reds_stream_free(channel->stream);
-- 
1.7.7.6

_______________________________________________
Spice-devel mailing list
Spice-devel@xxxxxxxxxxxxxxxxxxxxx
http://lists.freedesktop.org/mailman/listinfo/spice-devel


[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux]     [Linux OMAP]     [Linux MIPS]     [ECOS]     [Asterisk Internet PBX]     [Linux API]     [Monitors]