Blame SOURCES/0002-red_channel-add-ref-count-to-RedClient.patch

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