diff options
author | Will Thompson <will@willthompson.co.uk> | 2013-08-28 08:27:52 +0100 |
---|---|---|
committer | Will Thompson <will@willthompson.co.uk> | 2013-08-28 08:40:17 +0100 |
commit | b88fa165e855a50fd479aeeb9b8406a526b73773 (patch) | |
tree | b386123e0eb3c03b6591bf760c430729be229e22 /plugins | |
parent | 3976b375d5029e07856fe13eb5f580223e23567b (diff) |
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?
Diffstat (limited to 'plugins')
-rw-r--r-- | plugins/console/channel-manager.c | 27 | ||||
-rw-r--r-- | 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 48c814f2a..3d826db1c 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 8ec4adc0a..5e7a8b94d 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; }; |