[telepathy-mission-control/master] _mcd_dispatch_operation_set_handler_failed: fail any pending HandleWith calls if the nominated handler fails HandleChannels
Simon McVittie
simon.mcvittie at collabora.co.uk
Wed Oct 28 14:15:40 PDT 2009
This is a behaviour change: HandleWith with a non-empty argument will
no longer count as general approval; so in
dispatcher/handle-channels-fails, when the first client fails, the second
won't run immediately.
---
src/mcd-dispatch-operation.c | 28 +++++++++++-
test/twisted/dispatcher/handle-channels-fails.py | 51 +++++++++++++++++++---
2 files changed, 71 insertions(+), 8 deletions(-)
diff --git a/src/mcd-dispatch-operation.c b/src/mcd-dispatch-operation.c
index b70015d..d89941e 100644
--- a/src/mcd-dispatch-operation.c
+++ b/src/mcd-dispatch-operation.c
@@ -1521,8 +1521,11 @@ _mcd_dispatch_operation_check_finished (McdDispatchOperation *self)
static void
_mcd_dispatch_operation_set_handler_failed (McdDispatchOperation *self,
- const gchar *bus_name)
+ const gchar *bus_name,
+ const GError *error)
{
+ GList *iter, *next;
+
if (self->priv->failed_handlers == NULL)
{
self->priv->failed_handlers = g_hash_table_new_full (g_str_hash,
@@ -1534,6 +1537,27 @@ _mcd_dispatch_operation_set_handler_failed (McdDispatchOperation *self,
* will do nicely */
g_hash_table_insert (self->priv->failed_handlers, g_strdup (bus_name),
self->priv->failed_handlers);
+
+ for (iter = g_queue_peek_head_link (self->priv->approvals);
+ iter != NULL;
+ iter = next)
+ {
+ Approval *approval = iter->data;
+
+ /* do this before we potentially free the list element */
+ next = iter->next;
+
+ /* If this approval wanted the same handler that just failed, then
+ * we can assume that's not going to happen. */
+ if (approval->type == APPROVAL_TYPE_HANDLE_WITH &&
+ !tp_strdiff (approval->client_bus_name, bus_name))
+ {
+ dbus_g_method_return_error (approval->context, error);
+ approval->context = NULL;
+ approval_free (approval);
+ g_queue_delete_link (self->priv->approvals, iter);
+ }
+ }
}
static gboolean
@@ -1624,7 +1648,7 @@ _mcd_dispatch_operation_handle_channels_cb (TpClient *client,
DEBUG ("error: %s", error->message);
_mcd_dispatch_operation_set_handler_failed (self,
- tp_proxy_get_bus_name (client));
+ tp_proxy_get_bus_name (client), error);
}
else
{
diff --git a/test/twisted/dispatcher/handle-channels-fails.py b/test/twisted/dispatcher/handle-channels-fails.py
index 7f532d7..5c19733 100644
--- a/test/twisted/dispatcher/handle-channels-fails.py
+++ b/test/twisted/dispatcher/handle-channels-fails.py
@@ -156,22 +156,61 @@ def test(q, bus, mc):
# Empathy rejects the channels
q.dbus_raise(e.message, cs.NOT_AVAILABLE, 'Blind drunk', bus=empathy_bus)
+ e = q.expect('dbus-error', method='HandleWith')
+ assert e.error.get_dbus_name() == cs.NOT_AVAILABLE
+ assert e.error.get_dbus_message() == 'Blind drunk'
+
+ # The channels no longer count as having been approved. Check that MC
+ # doesn't carry on regardless
+ forbidden = [EventPattern('dbus-method-call', method='HandleChannels')]
+ q.forbid_events(forbidden)
+ sync_dbus(bus, q, mc)
+ q.unforbid_events(forbidden)
+
+ if 0: # FIXME: in future this should be what happens...
+ # I'm Feeling Lucky. It might work if I try again? Maybe?
+ call_async(q, cdo_iface, 'HandleWith',
+ cs.tp_name_prefix + '.Client.Empathy')
+
+ # Empathy is asked to handle the channels, again
+ e = q.expect('dbus-method-call',
+ path=empathy.object_path,
+ interface=cs.HANDLER, method='HandleChannels',
+ handled=False)
+
+ # Empathy rejects the channels, again
+ q.dbus_raise(e.message, cs.NOT_CAPABLE, 'Still drunk', bus=empathy_bus)
+
+ e = q.expect('dbus-error', method='HandleWith')
+ assert e.error.get_dbus_name() == cs.NOT_CAPABLE
+ assert e.error.get_dbus_message() == 'Still drunk'
+
+ # OK, OK, is anyone else competent enough to handle them?
+ # (Also, assert that MC doesn't offer them back to Empathy, knowing that
+ # it already tried and failed)
+ forbidden = [EventPattern('dbus-method-call', method='HandleChannels',
+ path=empathy.object_path)]
+ q.forbid_events(forbidden)
+ call_async(q, cdo_iface, 'HandleWith', '')
+
# Kopete is asked to handle the channels
- (k,) = q.expect_many(
- EventPattern(
- 'dbus-method-call',
+ k = q.expect('dbus-method-call',
path=kopete.object_path,
interface=cs.HANDLER, method='HandleChannels',
- handled=False),
- )
+ handled=False)
# Kopete rejects the channels too
q.dbus_raise(k.message, cs.NOT_AVAILABLE, 'Also blind drunk',
bus=kopete_bus)
+ e = q.expect('dbus-error', method='HandleWith')
+
+ if 0: # FIXME: at the moment the error is a generic "no more handlers"
+ assert e.error.get_dbus_name() == cs.NOT_AVAILABLE
+ assert e.error.get_dbus_message() == 'Also blind drunk'
+
# MC gives up and closes the channel. This is the end of the CDO.
q.expect_many(
- EventPattern('dbus-error', method='HandleWith'),
EventPattern('dbus-method-call', path=chan.object_path,
interface=cs.CHANNEL, method='Close', args=[]),
EventPattern('dbus-signal', interface=cs.CDO, signal='Finished'),
--
1.5.6.5
More information about the telepathy-commits
mailing list