[next] telepathy-glib: TpContact: stop keeping strong ref on its connection
Xavier Claessens
xclaesse at kemper.freedesktop.org
Tue Jun 26 02:38:46 PDT 2012
Module: telepathy-glib
Branch: next
Commit: 599eb54867b81df2b4f0229087945b99dcf88bf6
URL: http://cgit.freedesktop.org/telepathy/telepathy-glib/commit/?id=599eb54867b81df2b4f0229087945b99dcf88bf6
Author: Xavier Claessens <xavier.claessens at collabora.co.uk>
Date: Fri Jun 1 17:28:54 2012 +0200
TpContact: stop keeping strong ref on its connection
Reset TpContact::connection to NULL when connection is disposed
https://bugs.freedesktop.org/show_bug.cgi?id=49373
---
telepathy-glib/connection.c | 18 +-----------------
telepathy-glib/contact.c | 24 +++++++++++-------------
2 files changed, 12 insertions(+), 30 deletions(-)
diff --git a/telepathy-glib/connection.c b/telepathy-glib/connection.c
index 56bbbed..b5040ed 100644
--- a/telepathy-glib/connection.c
+++ b/telepathy-glib/connection.c
@@ -1027,19 +1027,6 @@ tp_connection_invalidated (TpConnection *self)
tp_proxy_pending_call_cancel (self->priv->introspection_call);
self->priv->introspection_call = NULL;
}
-
- /* Drop the ref we have on all roster contacts, this is to break the refcycle
- * we have between TpConnection and TpContact, otherwise self would never
- * run dispose.
- * Note that invalidated is also called from dispose, so self->priv->roster
- * could already be NULL.
- *
- * FIXME: When we decide to break tp-glib API/guarantees, we should stop
- * TpContact taking a strong ref on its TpConnection and force user to keep
- * a ref on the TpConnection to use its TpContact, this would avoid the
- * refcycle completely. */
- if (self->priv->roster != NULL)
- g_hash_table_remove_all (self->priv->roster);
}
static void
@@ -1156,10 +1143,7 @@ tp_connection_constructed (GObject *object)
tp_cli_dbus_properties_call_get_all (self, -1,
TP_IFACE_CONNECTION, _tp_connection_got_properties, NULL, NULL, NULL);
- /* Give a chance to TpAccount to know about invalidated connection before we
- * unref all roster contacts. This is to let applications properly remove all
- * contacts at once instead of getting weak notify on each. */
- g_signal_connect_after (self, "invalidated",
+ g_signal_connect (self, "invalidated",
G_CALLBACK (tp_connection_invalidated), NULL);
}
diff --git a/telepathy-glib/contact.c b/telepathy-glib/contact.c
index 8ea339a..cb20b8b 100644
--- a/telepathy-glib/contact.c
+++ b/telepathy-glib/contact.c
@@ -356,7 +356,7 @@ typedef enum {
struct _TpContactPrivate {
/* basics */
- TpConnection *connection;
+ TpConnection *connection; /* Weakref */
TpHandle handle;
gchar *identifier;
ContactFeatureFlags has_features;
@@ -992,11 +992,13 @@ tp_contact_set_contact_groups_finish (TpContact *self,
void
_tp_contact_connection_disposed (TpContact *contact)
{
- /* The connection has gone away, so we no longer have a meaningful handle,
- * and will never have one again. */
- g_assert (contact->priv->handle != 0);
- contact->priv->handle = 0;
- g_object_notify ((GObject *) contact, "handle");
+ /* This is called from TpConnection::dispose. It is necessary to set
+ * priv->connection to NULL sooner than a weak-notify would do, to prevent
+ * TpContact:dispose from calling _tp_connection_remove_contact() when
+ * TpConnection will unref its roster contacts. */
+ g_assert (contact->priv->connection != NULL);
+ contact->priv->connection = NULL;
+ g_object_notify ((GObject *) contact, "connection");
}
static void
@@ -1004,17 +1006,13 @@ tp_contact_dispose (GObject *object)
{
TpContact *self = TP_CONTACT (object);
- if (self->priv->handle != 0)
+ if (self->priv->connection != NULL)
{
- g_assert (self->priv->connection != NULL);
-
_tp_connection_remove_contact (self->priv->connection,
self->priv->handle, self);
-
- self->priv->handle = 0;
+ self->priv->connection = NULL;
}
- tp_clear_object (&self->priv->connection);
tp_clear_pointer (&self->priv->location, g_hash_table_unref);
tp_clear_object (&self->priv->capabilities);
tp_clear_object (&self->priv->avatar_file);
@@ -1150,7 +1148,7 @@ tp_contact_set_property (GObject *object,
{
case PROP_CONNECTION:
g_assert (self->priv->connection == NULL); /* construct only */
- self->priv->connection = g_value_dup_object (value);
+ self->priv->connection = g_value_get_object (value);
break;
case PROP_HANDLE:
g_assert (self->priv->handle == 0); /* construct only */
More information about the telepathy-commits
mailing list