summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWill Thompson <will@willthompson.co.uk>2013-08-28 08:27:52 +0100
committerWill Thompson <will@willthompson.co.uk>2013-08-28 08:40:17 +0100
commitb88fa165e855a50fd479aeeb9b8406a526b73773 (patch)
treeb386123e0eb3c03b6591bf760c430729be229e22
parent3976b375d5029e07856fe13eb5f580223e23567b (diff)
downloadtelepathy-gabble-b88fa165e855a50fd479aeeb9b8406a526b73773.tar.gz
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?
-rw-r--r--plugins/console/channel-manager.c27
-rw-r--r--plugins/console/channel-manager.h2
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;
};