diff options
author | Will Thompson <will.thompson@collabora.co.uk> | 2012-03-30 09:00:50 +0100 |
---|---|---|
committer | Will Thompson <will.thompson@collabora.co.uk> | 2012-03-30 15:32:45 +0100 |
commit | ecbbb72e7d11951a13514151cdf16112e09e608c (patch) | |
tree | 7ab1cc7ddd7332378270a99e00975a1c1303e62d /telepathy-glib/dbus-tube-channel.c | |
parent | a3725ba5c52443bdad1d6bf87230bd01af4cf53a (diff) | |
download | telepathy-glib-ecbbb72e7d11951a13514151cdf16112e09e608c.tar.gz |
dbus-tube: fail offer/accept if channel is invalidated
Diffstat (limited to 'telepathy-glib/dbus-tube-channel.c')
-rw-r--r-- | telepathy-glib/dbus-tube-channel.c | 42 |
1 files changed, 39 insertions, 3 deletions
diff --git a/telepathy-glib/dbus-tube-channel.c b/telepathy-glib/dbus-tube-channel.c index dfbb710dc..2967fdbe9 100644 --- a/telepathy-glib/dbus-tube-channel.c +++ b/telepathy-glib/dbus-tube-channel.c @@ -89,7 +89,8 @@ tp_dbus_tube_channel_dispose (GObject *obj) TpDBusTubeChannel *self = (TpDBusTubeChannel *) obj; tp_clear_pointer (&self->priv->parameters, g_hash_table_unref); - g_clear_object (&self->priv->result); + /* If priv->result isn't NULL, it owns a ref to self. */ + g_warn_if_fail (self->priv->result == NULL); tp_clear_pointer (&self->priv->address, g_free); G_OBJECT_CLASS (tp_dbus_tube_channel_parent_class)->dispose (obj); @@ -123,8 +124,19 @@ tp_dbus_tube_channel_get_property (GObject *object, static void complete_operation (TpDBusTubeChannel *self) { - g_simple_async_result_complete (self->priv->result); - g_clear_object (&self->priv->result); + TpDBusTubeChannelPrivate *priv = self->priv; + GSimpleAsyncResult *result = priv->result; + + /* This dance is to ensure that we don't accidentally manipulate priv->result + * while calling out to user code. For instance, someone might call + * tp_proxy_invalidate() on us, which winds up landing us in here via our + * handler for that signal. + */ + g_assert (priv->result != NULL); + result = priv->result; + priv->result = NULL; + g_simple_async_result_complete (result); + g_object_unref (result); } static void @@ -172,6 +184,27 @@ check_tube_open (TpDBusTubeChannel *self) } static void +dbus_tube_invalidated_cb ( + TpProxy *proxy, + guint domain, + gint code, + gchar *message, + gpointer user_data) +{ + TpDBusTubeChannel *self = TP_DBUS_TUBE_CHANNEL (proxy); + TpDBusTubeChannelPrivate *priv = self->priv; + GError error = { domain, code, message }; + + if (priv->result != NULL) + { + DEBUG ("Tube invalidated: '%s'; failing pending offer/accept method call", + message); + g_simple_async_result_set_from_error (priv->result, &error); + complete_operation (self); + } +} + +static void tube_state_changed_cb (TpChannel *channel, TpTubeChannelState state, gpointer user_data, @@ -245,6 +278,9 @@ tp_dbus_tube_channel_constructed (GObject *obj) TP_HASH_TYPE_STRING_VARIANT_MAP, params); } } + + g_signal_connect (self, "invalidated", + G_CALLBACK (dbus_tube_invalidated_cb), NULL); } static void |