telepathy-gabble: console: hold a weak ref to GabblePluginConnection

Simon McVittie smcv at kemper.freedesktop.org
Mon Oct 14 08:21:20 PDT 2013


Module: telepathy-gabble
Branch: master
Commit: b88fa165e855a50fd479aeeb9b8406a526b73773
URL:    http://cgit.freedesktop.org/telepathy/telepathy-gabble/commit/?id=b88fa165e855a50fd479aeeb9b8406a526b73773

Author: Will Thompson <will at willthompson.co.uk>
Date:   Wed Aug 28 08:27:52 2013 +0100

console: hold a weak ref to GabblePluginConnection

As Simon suggested on
<https://bugs.freedesktop.org/show_bug.cgi?id=66085#c1>:

> + /* Not reffing this: the connection owns all channel managers, so it
> + * must outlive us. Taking a reference leads to a cycle.
> + */
> + self->plugin_connection = g_value_get_object (value);
>
> Weak ref, or drop it on DISCONNECTED state?

---

 plugins/console/channel-manager.c |   27 ++++++++++++++++++---------
 plugins/console/channel-manager.h |    2 +-
 2 files changed, 19 insertions(+), 10 deletions(-)

diff --git a/plugins/console/channel-manager.c b/plugins/console/channel-manager.c
index 48c814f..3d826db 100644
--- a/plugins/console/channel-manager.c
+++ b/plugins/console/channel-manager.c
@@ -46,6 +46,7 @@ static void gabble_console_channel_manager_close_all (
 static void
 gabble_console_channel_manager_init (GabbleConsoleChannelManager *self)
 {
+  g_weak_ref_init (&self->plugin_connection_ref, NULL);
 }
 
 
@@ -53,12 +54,17 @@ static void
 gabble_console_channel_manager_constructed (GObject *object)
 {
   GabbleConsoleChannelManager *self = GABBLE_CONSOLE_CHANNEL_MANAGER (object);
+  GabblePluginConnection *plugin_connection;
 
   G_OBJECT_CLASS (gabble_console_channel_manager_parent_class)->constructed (object);
 
-  g_return_if_fail (self->plugin_connection != NULL);
-  g_signal_connect_object (self->plugin_connection, "status-changed",
-      G_CALLBACK (connection_status_changed_cb), self, 0);
+  plugin_connection = g_weak_ref_get (&self->plugin_connection_ref);
+  if (plugin_connection != NULL)
+    {
+      g_signal_connect_object (plugin_connection, "status-changed",
+          G_CALLBACK (connection_status_changed_cb), self, 0);
+      g_object_unref (plugin_connection);
+    }
 }
 
 
@@ -74,10 +80,7 @@ gabble_console_channel_manager_set_property (
   switch (property_id)
     {
       case PROP_CONNECTION:
-        /* Not reffing this: the connection owns all channel managers, so it
-         * must outlive us. Taking a reference leads to a cycle.
-         */
-        self->plugin_connection = g_value_get_object (value);
+        g_weak_ref_set (&self->plugin_connection_ref, g_value_get_object (value));
         break;
       default:
         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -96,7 +99,7 @@ gabble_console_channel_manager_get_property (
   switch (property_id)
     {
       case PROP_CONNECTION:
-        g_value_set_object (value, self->plugin_connection);
+        g_value_take_object (value, g_weak_ref_get (&self->plugin_connection_ref));
         break;
       default:
         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -111,6 +114,7 @@ gabble_console_channel_manager_dispose (
   GabbleConsoleChannelManager *self = GABBLE_CONSOLE_CHANNEL_MANAGER (object);
 
   gabble_console_channel_manager_close_all (self);
+  g_weak_ref_clear (&self->plugin_connection_ref);
 
   G_OBJECT_CLASS (gabble_console_channel_manager_parent_class)->dispose (object);
 }
@@ -211,6 +215,7 @@ gabble_console_channel_manager_create_channel (
     GHashTable *request_properties)
 {
   GabbleConsoleChannelManager *self = GABBLE_CONSOLE_CHANNEL_MANAGER (manager);
+  GabblePluginConnection *connection;
   TpBaseChannel *channel = NULL;
   GError *error = NULL;
   GSList *request_tokens;
@@ -234,8 +239,11 @@ gabble_console_channel_manager_create_channel (
           &error))
     goto error;
 
+  connection = g_weak_ref_get (&self->plugin_connection_ref);
+  g_return_val_if_fail (connection != NULL, FALSE);
+
   channel = g_object_new (GABBLE_TYPE_CONSOLE_CHANNEL,
-      "connection", self->plugin_connection,
+      "connection", connection,
       NULL);
   tp_base_channel_register (channel);
   g_signal_connect (channel, "closed", (GCallback) console_channel_closed_cb,
@@ -247,6 +255,7 @@ gabble_console_channel_manager_create_channel (
       TP_EXPORTABLE_CHANNEL (channel), request_tokens);
   g_slist_free (request_tokens);
 
+  g_object_unref (connection);
   return TRUE;
 
 error:
diff --git a/plugins/console/channel-manager.h b/plugins/console/channel-manager.h
index 8ec4adc..5e7a8b9 100644
--- a/plugins/console/channel-manager.h
+++ b/plugins/console/channel-manager.h
@@ -30,7 +30,7 @@ struct _GabbleConsoleChannelManagerClass {
 struct _GabbleConsoleChannelManager {
   GObject parent;
 
-  GabblePluginConnection *plugin_connection;
+  GWeakRef plugin_connection_ref;
   GQueue console_channels;
 };
 



More information about the telepathy-commits mailing list