summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlberto Mardegan <mardy@users.sourceforge.net>2007-05-11 07:18:53 +0000
committerAlberto Mardegan <mardy@users.sourceforge.net>2007-05-11 07:18:53 +0000
commitca9838ba07df0f549260401a6cff2ba1a69bd819 (patch)
tree312ccc886ef50e503fb7f2838a4abd8006b1d370 /src
parentc7aff163edf4c419b417d6fcf8b91d70d017a953 (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.c53
-rw-r--r--src/mcd-channel.h1
-rw-r--r--src/mcd-dispatcher.c43
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)