diff options
author | Alberto Mardegan <mardy@users.sourceforge.net> | 2007-05-11 07:18:53 +0000 |
---|---|---|
committer | Alberto Mardegan <mardy@users.sourceforge.net> | 2007-05-11 07:18:53 +0000 |
commit | ca9838ba07df0f549260401a6cff2ba1a69bd819 (patch) | |
tree | 312ccc886ef50e503fb7f2838a4abd8006b1d370 /src | |
parent | c7aff163edf4c419b417d6fcf8b91d70d017a953 (diff) |
* src/mcd-channel.[hc]:
Add mcd_channel_is_missed() method to know if a channel has been
accepted by the local user.
* src/mcd-dispatcher.c:
If a channel is aborted right before the channel handle starts, report
a dispatch failure.
git-svn-id: https://mission-control.svn.sourceforge.net/svnroot/mission-control/trunk@37 d91c8aed-3f2b-0410-a83d-924a1c20a0ba
Diffstat (limited to 'src')
-rw-r--r-- | src/mcd-channel.c | 53 | ||||
-rw-r--r-- | src/mcd-channel.h | 1 | ||||
-rw-r--r-- | src/mcd-dispatcher.c | 43 |
3 files changed, 87 insertions, 10 deletions
diff --git a/src/mcd-channel.c b/src/mcd-channel.c index 49a4cdb3..3c62ad3b 100644 --- a/src/mcd-channel.c +++ b/src/mcd-channel.c @@ -63,6 +63,8 @@ typedef struct _McdChannelPrivate /* Pending members */ GArray *pending_local_members; gboolean members_accepted; + gboolean missed; + guint self_handle; McdChannelStatus status; gchar *channel_name; @@ -160,6 +162,24 @@ on_channel_members_changed (DBusGProxy * group_proxy, } /* FIXME: We should also remove members from the local pending * array, even if we don't need the info */ + if (removed && removed->len > 0) + { + int i; + + if (actor != priv->self_handle) + { + for (i = 0; i < removed->len; i++) + { + if (actor == g_array_index (removed, guint, i)) + { + /* the remote removed itself; if we didn't accept the call, + * it's a missed channel */ + if (!priv->members_accepted) priv->missed = TRUE; + break; + } + } + } + } } static void @@ -252,6 +272,22 @@ _mcd_channel_release_tp_channel (McdChannel *channel, gboolean close_channel) } static void +get_self_handle_cb (DBusGProxy *proxy, guint self_handle, GError *error, + gpointer userdata) + +{ + McdChannelPrivate *priv = (McdChannelPrivate *) userdata; + if (error) + { + g_warning ("%s: get_self_handle failed: %s", G_STRFUNC, + error->message); + g_error_free (error); + } + else + priv->self_handle = self_handle; +} + +static void _mcd_channel_set_property (GObject * obj, guint prop_id, const GValue * val, GParamSpec * pspec) { @@ -295,6 +331,8 @@ _mcd_channel_set_property (GObject * obj, guint prop_id, tp_chan_iface_group_get_local_pending_members_async (group_iface, get_local_pending_cb, channel); + tp_chan_iface_group_get_self_handle_async (group_iface, + get_self_handle_cb, priv); } /* We want to track the channel object closes, because we need to do * some cleanups when it's gone */ @@ -807,3 +845,18 @@ mcd_channel_get_name (McdChannel *channel) return priv->channel_name; } +/** + * mcd_channel_is_missed: + * @channel: the #McdChannel. + * + * Return %TRUE if the remote party removed itself before we could join the + * channel. + * + * Returns: %TRUE if the channel is missed. + */ +gboolean +mcd_channel_is_missed (McdChannel *channel) +{ + return MCD_CHANNEL_PRIV (channel)->missed; +} + diff --git a/src/mcd-channel.h b/src/mcd-channel.h index c668e508..6a075b6b 100644 --- a/src/mcd-channel.h +++ b/src/mcd-channel.h @@ -101,6 +101,7 @@ TelepathyHandleType mcd_channel_get_handle_type (McdChannel *channel); gint mcd_channel_get_flags (McdChannel *channel); GPtrArray* mcd_channel_get_members (McdChannel *channel); const gchar *mcd_channel_get_name (McdChannel *channel); +gboolean mcd_channel_is_missed (McdChannel *channel); G_END_DECLS #endif /* MCD_CHANNEL_H */ diff --git a/src/mcd-dispatcher.c b/src/mcd-dispatcher.c index 8fd41f3b..3abd084a 100644 --- a/src/mcd-dispatcher.c +++ b/src/mcd-dispatcher.c @@ -96,6 +96,13 @@ struct iface_chains_t GList *chain_out; }; +struct cancel_call_data +{ + DBusGProxy *handler_proxy; + DBusGProxyCall *call; + McdDispatcher *dispatcher; +}; + enum { PROP_0, @@ -498,11 +505,24 @@ disconnect_proxy_destry_cb (McdChannel *channel, DBusGProxy *channelhandler) } static void -cancel_proxy_call (McdChannel *channel, DBusGProxyCall *call) +cancel_proxy_call (McdChannel *channel, struct cancel_call_data *call_data) { - DBusGProxy *proxy = g_object_steal_data (G_OBJECT (channel), - "cancel_proxy_call_userdata"); - dbus_g_proxy_cancel_call (proxy, call); + GError *mc_error = NULL; + + dbus_g_proxy_cancel_call (call_data->handler_proxy, call_data->call); + + g_debug ("%s: signalling Handle channel failed", G_STRFUNC); + + /* We can't reliably map channel handler error codes to MC error + * codes. So just using generic error message. + */ + mc_error = g_error_new (MC_ERROR, MC_CHANNEL_REQUEST_GENERIC_ERROR, + "Channel aborted"); + + g_signal_emit (call_data->dispatcher, + mcd_dispatcher_signals[DISPATCH_FAILED], 0, + channel, mc_error); + g_error_free (mc_error); } static void @@ -517,7 +537,7 @@ _mcd_dispatcher_handle_channel_async_cb (DBusGProxy * proxy, GError * error, McdChannelHandler *chandler = g_hash_table_lookup (priv->channel_handler_hash, mcd_channel_get_channel_type (channel)); - g_object_steal_data (G_OBJECT (channel), "cancel_proxy_call_userdata"); + g_signal_handlers_disconnect_matched (channel, G_SIGNAL_MATCH_FUNC, 0, 0, NULL, cancel_proxy_call, NULL); @@ -623,6 +643,7 @@ _mcd_dispatcher_start_channel_handler (McdDispatcherContext * context) } else { + struct cancel_call_data *call_data; DBusGProxyCall *call; TpConn *tp_conn; @@ -663,10 +684,12 @@ _mcd_dispatcher_start_channel_handler (McdDispatcherContext * context) mcd_channel_get_handle (channel), _mcd_dispatcher_handle_channel_async_cb, context); - g_object_set_data (G_OBJECT (channel), "cancel_proxy_call_userdata", - handler_proxy); - g_signal_connect (channel, "abort", G_CALLBACK(cancel_proxy_call), - call); + call_data = g_malloc (sizeof (struct cancel_call_data)); + call_data->call = call; + call_data->handler_proxy = handler_proxy; + call_data->dispatcher = context->dispatcher; + g_signal_connect_data (channel, "abort", G_CALLBACK(cancel_proxy_call), + call_data, (GClosureNotify)g_free, 0); g_object_unref (tp_conn); } } @@ -744,7 +767,7 @@ _mcd_dispatcher_enter_state_machine (McdDispatcher *dispatcher, /* Context must be destroyed when the channel is destroyed */ g_object_ref (channel); /* We hold separate refs for state machine */ - g_signal_connect (channel, "abort", G_CALLBACK (on_channel_abort_context), + g_signal_connect_after (channel, "abort", G_CALLBACK (on_channel_abort_context), context); if (chain) |