[telepathy-mission-control/master] McdDispatchOperation: allow delaying ChannelLost and Finished
Simon McVittie
simon.mcvittie at collabora.co.uk
Mon Apr 20 07:13:28 PDT 2009
---
src/mcd-dispatch-operation-priv.h | 5 ++
src/mcd-dispatch-operation.c | 77 ++++++++++++++++++++++++++++++++++++-
2 files changed, 81 insertions(+), 1 deletions(-)
diff --git a/src/mcd-dispatch-operation-priv.h b/src/mcd-dispatch-operation-priv.h
index b68a177..5d61977 100644
--- a/src/mcd-dispatch-operation-priv.h
+++ b/src/mcd-dispatch-operation-priv.h
@@ -33,6 +33,11 @@ G_GNUC_INTERNAL McdDispatchOperation *_mcd_dispatch_operation_new (
G_GNUC_INTERNAL void _mcd_dispatch_operation_lose_channel (
McdDispatchOperation *self, McdChannel *channel, GList **channels);
+G_GNUC_INTERNAL void _mcd_dispatch_operation_block_finished (
+ McdDispatchOperation *self);
+G_GNUC_INTERNAL void _mcd_dispatch_operation_unblock_finished (
+ McdDispatchOperation *self);
+
G_END_DECLS
#endif
diff --git a/src/mcd-dispatch-operation.c b/src/mcd-dispatch-operation.c
index f000155..2dbfa92 100644
--- a/src/mcd-dispatch-operation.c
+++ b/src/mcd-dispatch-operation.c
@@ -75,6 +75,7 @@ struct _McdDispatchOperationPrivate
gchar *object_path;
GStrv possible_handlers;
GHashTable *properties;
+ gsize block_finished;
/* Results */
guint finished : 1;
@@ -86,7 +87,11 @@ struct _McdDispatchOperationPrivate
McdConnection *connection;
+ /* Owned McdChannels we're dispatching */
GList *channels;
+ /* Owned McdChannels for which we can't emit ChannelLost yet, in
+ * reverse chronological order */
+ GList *lost_channels;
};
enum
@@ -200,7 +205,11 @@ mcd_dispatch_operation_finish (McdDispatchOperation *operation)
McdDispatchOperationPrivate *priv = operation->priv;
priv->finished = TRUE;
- mc_svc_channel_dispatch_operation_emit_finished (operation);
+
+ if (priv->block_finished == 0)
+ {
+ mc_svc_channel_dispatch_operation_emit_finished (operation);
+ }
}
static void
@@ -624,6 +633,14 @@ _mcd_dispatch_operation_lose_channel (McdDispatchOperation *self,
g_critical ("McdChannel has already lost its TpChannel: %p",
channel);
}
+ else if (self->priv->block_finished)
+ {
+ /* We're still invoking approvers, so we're not allowed to talk
+ * about it right now. Instead, save the signal for later. */
+ self->priv->lost_channels =
+ g_list_prepend (self->priv->lost_channels,
+ g_object_ref (channel));
+ }
else
{
const GError *error = mcd_channel_get_error (channel);
@@ -647,3 +664,61 @@ _mcd_dispatch_operation_lose_channel (McdDispatchOperation *self,
}
}
}
+
+void
+_mcd_dispatch_operation_block_finished (McdDispatchOperation *self)
+{
+ g_return_if_fail (MCD_IS_DISPATCH_OPERATION (self));
+ g_return_if_fail (!self->priv->finished);
+
+ self->priv->block_finished++;
+}
+
+void
+_mcd_dispatch_operation_unblock_finished (McdDispatchOperation *self)
+{
+ g_return_if_fail (MCD_IS_DISPATCH_OPERATION (self));
+ g_return_if_fail (self->priv->block_finished > 0);
+
+ self->priv->block_finished--;
+
+ if (self->priv->block_finished == 0)
+ {
+ GList *lost_channels;
+
+ /* get the lost channels into chronological order, and steal them from
+ * the object*/
+ lost_channels = g_list_reverse (self->priv->lost_channels);
+ self->priv->lost_channels = NULL;
+
+ while (lost_channels != NULL)
+ {
+ McdChannel *channel = lost_channels->data;
+ const gchar *object_path = mcd_channel_get_object_path (channel);
+
+ if (object_path == NULL)
+ {
+ /* This shouldn't happen, but McdChannel is twisty enough
+ * that I can't be sure */
+ g_critical ("McdChannel has already lost its TpChannel: %p",
+ channel);
+ }
+ else
+ {
+ const GError *error = mcd_channel_get_error (channel);
+ gchar *error_name = _mcd_build_error_string (error);
+
+ mc_svc_channel_dispatch_operation_emit_channel_lost (self,
+ object_path, error_name, error->message);
+ g_free (error_name);
+ }
+
+ lost_channels = g_list_delete_link (lost_channels, lost_channels);
+ }
+
+ if (self->priv->finished)
+ {
+ mc_svc_channel_dispatch_operation_emit_finished (self);
+ }
+ }
+}
--
1.5.6.5
More information about the telepathy-commits
mailing list