97 lines
2.9 KiB
Diff
97 lines
2.9 KiB
Diff
|
From aab45618cc12799d5f7351ef8832ae73b33057c7 Mon Sep 17 00:00:00 2001
|
||
|
From: Yonit Halperin <yhalperi@redhat.com>
|
||
|
Date: Fri, 26 Jul 2013 13:45:16 -0400
|
||
|
Subject: [PATCH 2/8] red_channel: add ref count to RedClient
|
||
|
|
||
|
---
|
||
|
server/red_channel.c | 23 ++++++++++++++++++++---
|
||
|
server/red_channel.h | 17 +++++++++++++++--
|
||
|
2 files changed, 35 insertions(+), 5 deletions(-)
|
||
|
|
||
|
diff --git a/server/red_channel.c b/server/red_channel.c
|
||
|
index 0d74413..9168b8a 100644
|
||
|
--- a/server/red_channel.c
|
||
|
+++ b/server/red_channel.c
|
||
|
@@ -1932,10 +1932,29 @@ RedClient *red_client_new(int migrated)
|
||
|
pthread_mutex_init(&client->lock, NULL);
|
||
|
client->thread_id = pthread_self();
|
||
|
client->during_target_migrate = migrated;
|
||
|
+ client->refs = 1;
|
||
|
|
||
|
return client;
|
||
|
}
|
||
|
|
||
|
+RedClient *red_client_ref(RedClient *client)
|
||
|
+{
|
||
|
+ spice_assert(client);
|
||
|
+ client->refs++;
|
||
|
+ return client;
|
||
|
+}
|
||
|
+
|
||
|
+RedClient *red_client_unref(RedClient *client)
|
||
|
+{
|
||
|
+ if (!--client->refs) {
|
||
|
+ spice_debug("release client=%p", client);
|
||
|
+ pthread_mutex_destroy(&client->lock);
|
||
|
+ free(client);
|
||
|
+ return NULL;
|
||
|
+ }
|
||
|
+ return client;
|
||
|
+}
|
||
|
+
|
||
|
/* client mutex should be locked before this call */
|
||
|
static void red_channel_client_set_migration_seamless(RedChannelClient *rcc)
|
||
|
{
|
||
|
@@ -2012,9 +2031,7 @@ void red_client_destroy(RedClient *client)
|
||
|
spice_assert(rcc->send_data.size == 0);
|
||
|
red_channel_client_destroy(rcc);
|
||
|
}
|
||
|
-
|
||
|
- pthread_mutex_destroy(&client->lock);
|
||
|
- free(client);
|
||
|
+ red_client_unref(client);
|
||
|
}
|
||
|
|
||
|
/* client->lock should be locked */
|
||
|
diff --git a/server/red_channel.h b/server/red_channel.h
|
||
|
index ba299b6..0dd73ea 100644
|
||
|
--- a/server/red_channel.h
|
||
|
+++ b/server/red_channel.h
|
||
|
@@ -561,10 +561,25 @@ struct RedClient {
|
||
|
is called */
|
||
|
int seamless_migrate;
|
||
|
int num_migrated_channels; /* for seamless - number of channels that wait for migrate data*/
|
||
|
+ int refs;
|
||
|
};
|
||
|
|
||
|
RedClient *red_client_new(int migrated);
|
||
|
|
||
|
+/*
|
||
|
+ * disconnects all the client's channels (should be called from the client's thread)
|
||
|
+ */
|
||
|
+void red_client_destroy(RedClient *client);
|
||
|
+
|
||
|
+RedClient *red_client_ref(RedClient *client);
|
||
|
+
|
||
|
+/*
|
||
|
+ * releases the client resources when refs == 0.
|
||
|
+ * We assume the red_client_derstroy was called before
|
||
|
+ * we reached refs==0
|
||
|
+ */
|
||
|
+RedClient *red_client_unref(RedClient *client);
|
||
|
+
|
||
|
MainChannelClient *red_client_get_main(RedClient *client);
|
||
|
// main should be set once before all the other channels are created
|
||
|
void red_client_set_main(RedClient *client, MainChannelClient *mcc);
|
||
|
@@ -580,7 +595,5 @@ void red_client_semi_seamless_migrate_complete(RedClient *client); /* dst side *
|
||
|
int red_client_during_migrate_at_target(RedClient *client);
|
||
|
|
||
|
void red_client_migrate(RedClient *client);
|
||
|
-// disconnects all the client's channels (should be called from the client's thread)
|
||
|
-void red_client_destroy(RedClient *client);
|
||
|
|
||
|
#endif
|
||
|
--
|
||
|
1.8.3.1
|
||
|
|