summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--server/red_channel.c34
-rw-r--r--server/red_channel.h4
-rw-r--r--server/snd_worker.c2
3 files changed, 26 insertions, 14 deletions
diff --git a/server/red_channel.c b/server/red_channel.c
index 803804e1..18b69d32 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 de72fffb..aab7d2d0 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 3599c6ff..2746940f 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);