[telepathy-mission-control/master] McdDispatcher: look up channels in McdDispatchOperation, not McdDispatcherContext
Simon McVittie
simon.mcvittie at collabora.co.uk
Mon Nov 2 06:41:31 PST 2009
---
src/mcd-dispatch-operation-priv.h | 2 +-
src/mcd-dispatch-operation.c | 11 +----
src/mcd-dispatcher.c | 97 ++++++++++++++++++++-----------------
3 files changed, 54 insertions(+), 56 deletions(-)
diff --git a/src/mcd-dispatch-operation-priv.h b/src/mcd-dispatch-operation-priv.h
index 30990a7..6d9f823 100644
--- a/src/mcd-dispatch-operation-priv.h
+++ b/src/mcd-dispatch-operation-priv.h
@@ -84,7 +84,7 @@ G_GNUC_INTERNAL const GList *_mcd_dispatch_operation_peek_channels (
G_GNUC_INTERNAL GList *_mcd_dispatch_operation_dup_channels (
McdDispatchOperation *self);
G_GNUC_INTERNAL void _mcd_dispatch_operation_lose_channel (
- McdDispatchOperation *self, McdChannel *channel, GList **channels);
+ McdDispatchOperation *self, McdChannel *channel);
G_GNUC_INTERNAL GPtrArray *_mcd_dispatch_operation_dup_channel_details (
McdDispatchOperation *self);
diff --git a/src/mcd-dispatch-operation.c b/src/mcd-dispatch-operation.c
index 04806f0..edc92d5 100644
--- a/src/mcd-dispatch-operation.c
+++ b/src/mcd-dispatch-operation.c
@@ -1017,8 +1017,7 @@ _mcd_dispatch_operation_approve (McdDispatchOperation *self)
void
_mcd_dispatch_operation_lose_channel (McdDispatchOperation *self,
- McdChannel *channel,
- GList **channels)
+ McdChannel *channel)
{
GList *li = g_list_find (self->priv->channels, channel);
const gchar *object_path;
@@ -1030,14 +1029,6 @@ _mcd_dispatch_operation_lose_channel (McdDispatchOperation *self,
self->priv->channels = g_list_delete_link (self->priv->channels, li);
- /* Because the McdDispatcherContext has a borrowed copy of our list
- * of channels, we need to tell it the new head of the list, in case
- * we've just removed the first link. Further, we need to do this before
- * emitting any signals.
- *
- * This is amazingly fragile. */
- *channels = self->priv->channels;
-
object_path = mcd_channel_get_object_path (channel);
if (object_path == NULL)
diff --git a/src/mcd-dispatcher.c b/src/mcd-dispatcher.c
index 9a39542..a61834e 100644
--- a/src/mcd-dispatcher.c
+++ b/src/mcd-dispatcher.c
@@ -92,7 +92,6 @@ struct _McdDispatcherContext
McdDispatcher *dispatcher;
- GList *channels;
McdDispatchOperation *operation;
/* State-machine internal data fields: */
@@ -490,7 +489,7 @@ handle_channels_cb (TpClient *proxy, const GError *error, gpointer user_data,
GObject *weak_object)
{
McdDispatcherContext *context = user_data;
- GList *list;
+ const GList *list;
mcd_dispatcher_context_ref (context, "CTXREF02");
if (error)
@@ -505,7 +504,9 @@ handle_channels_cb (TpClient *proxy, const GError *error, gpointer user_data,
}
else
{
- for (list = context->channels; list != NULL; list = list->next)
+ for (list = _mcd_dispatch_operation_peek_channels (context->operation);
+ list != NULL;
+ list = list->next)
{
McdChannel *channel = list->data;
const gchar *unique_name;
@@ -712,11 +713,15 @@ mcd_dispatcher_handle_channels (McdDispatcherContext *context,
account_path = _mcd_dispatch_operation_get_account_path
(context->operation);
- channels_array = _mcd_channel_details_build_from_list (context->channels);
+ channels_array = _mcd_dispatch_operation_dup_channel_details
+ (context->operation);
user_action_time = 0; /* TODO: if we have a CDO, get it from there */
satisfied_requests = g_ptr_array_new ();
- for (cl = context->channels; cl != NULL; cl = cl->next)
+
+ for (cl = _mcd_dispatch_operation_peek_channels (context->operation);
+ cl != NULL;
+ cl = cl->next)
{
McdChannel *channel = MCD_CHANNEL (cl->data);
const GList *requests;
@@ -835,7 +840,7 @@ mcd_dispatcher_run_handlers (McdDispatcherContext *context)
DEBUG ("No possible handler still exists, giving up");
- channels = g_list_copy (context->channels);
+ channels = _mcd_dispatch_operation_dup_channels (context->operation);
for (list = channels; list != NULL; list = list->next)
{
@@ -845,6 +850,7 @@ mcd_dispatcher_run_handlers (McdDispatcherContext *context)
mcd_channel_take_error (channel, g_error_copy (&e));
_mcd_channel_undispatchable (channel);
+ g_object_unref (channel);
}
g_list_free (channels);
@@ -946,7 +952,7 @@ mcd_dispatcher_run_observers (McdDispatcherContext *context)
gpointer client_p;
sp_timestamp ("run observers");
- channels = context->channels;
+ channels = _mcd_dispatch_operation_peek_channels (context->operation);
observer_info = g_hash_table_new (g_str_hash, g_str_equal);
_mcd_client_registry_init_hash_iter (priv->clients, &iter);
@@ -1101,7 +1107,7 @@ mcd_dispatcher_run_approvers (McdDispatcherContext *context)
* approvers */
_mcd_dispatch_operation_inc_ado_pending (context->operation);
- channels = context->channels;
+ channels = _mcd_dispatch_operation_peek_channels (context->operation);
_mcd_client_registry_init_hash_iter (priv->clients, &iter);
while (g_hash_table_iter_next (&iter, NULL, &client_p))
{
@@ -1212,10 +1218,9 @@ _mcd_dispatcher_context_abort (McdDispatcherContext *context,
g_return_if_fail (context);
/* make a temporary copy, which is destroyed during the loop - otherwise
- * we'll be trying to iterate over context->channels at the same time
+ * we'll be trying to iterate over the list at the same time
* that mcd_mission_abort results in modifying it, which would be bad */
- list = g_list_copy (context->channels);
- g_list_foreach (list, (GFunc) g_object_ref, NULL);
+ list = _mcd_dispatch_operation_dup_channels (context->operation);
while (list != NULL)
{
@@ -1248,15 +1253,9 @@ on_channel_abort_context (McdChannel *channel, McdDispatcherContext *context)
* the operations below very unhappy */
mcd_dispatcher_context_ref (context, "CTXREF08");
- /* the CDO owns the linked list and we just borrow it; in case it's
- * the head of the list that we're deleting, we need to ask the CDO
- * to update our idea of what the list is before emitting any signals.
- *
- * FIXME: this is alarmingly fragile */
- _mcd_dispatch_operation_lose_channel (context->operation, channel,
- &(context->channels));
+ _mcd_dispatch_operation_lose_channel (context->operation, channel);
- if (context->channels == NULL)
+ if (_mcd_dispatch_operation_peek_channels (context->operation) == NULL)
{
DEBUG ("Nothing left in this context");
}
@@ -1289,7 +1288,7 @@ on_operation_finished (McdDispatchOperation *operation,
g_assert (!_mcd_dispatch_operation_has_observers_pending
(context->operation));
- if (context->channels == NULL)
+ if (_mcd_dispatch_operation_peek_channels (context->operation) == NULL)
{
DEBUG ("Nothing left to dispatch");
@@ -1298,12 +1297,14 @@ on_operation_finished (McdDispatchOperation *operation,
}
else if (_mcd_dispatch_operation_is_claimed (operation))
{
- GList *list;
+ const GList *list;
/* we don't release the client lock, in order to not run the handlers.
* But we have to mark all channels as dispatched, and free the
* @context */
- for (list = context->channels; list != NULL; list = list->next)
+ for (list = _mcd_dispatch_operation_peek_channels (context->operation);
+ list != NULL;
+ list = list->next)
{
McdChannel *channel = MCD_CHANNEL (list->data);
@@ -1360,14 +1361,13 @@ _mcd_dispatcher_enter_state_machine (McdDispatcher *dispatcher,
DEBUG ("CTXREF11 on %p", context);
context->ref_count = 1;
context->dispatcher = dispatcher;
- context->channels = channels;
context->chain = priv->filters;
DEBUG ("new dispatcher context %p for %s channel %p (%s): %s",
context, requested ? "requested" : "unrequested",
- context->channels->data,
- context->channels->next == NULL ? "only" : "and more",
- mcd_channel_get_object_path (context->channels->data));
+ channels->data,
+ channels->next == NULL ? "only" : "and more",
+ mcd_channel_get_object_path (channels->data));
priv->contexts = g_list_prepend (priv->contexts, context);
@@ -1892,7 +1892,7 @@ mcd_dispatcher_context_proceed (McdDispatcherContext *context)
goto no_more;
}
- if (context->channels == NULL)
+ if (_mcd_dispatch_operation_peek_channels (context->operation) == NULL)
{
DEBUG ("No channels left");
goto no_more;
@@ -1934,10 +1934,9 @@ mcd_dispatcher_context_forget_all (McdDispatcherContext *context)
g_return_if_fail (context);
/* make a temporary copy, which is destroyed during the loop - otherwise
- * we'll be trying to iterate over context->channels at the same time
+ * we'll be trying to iterate over the list at the same time
* that mcd_mission_abort results in modifying it, which would be bad */
- list = g_list_copy (context->channels);
- g_list_foreach (list, (GFunc) g_object_ref, NULL);
+ list = _mcd_dispatch_operation_dup_channels (context->operation);
while (list != NULL)
{
@@ -1946,7 +1945,9 @@ mcd_dispatcher_context_forget_all (McdDispatcherContext *context)
list = g_list_delete_link (list, list);
}
- g_return_if_fail (context->channels == NULL);
+ /* There should now be none left (they all aborted) */
+ g_return_if_fail (_mcd_dispatch_operation_peek_channels
+ (context->operation) == NULL);
}
/**
@@ -1966,8 +1967,7 @@ mcd_dispatcher_context_destroy_all (McdDispatcherContext *context)
g_return_if_fail (context);
- list = g_list_copy (context->channels);
- g_list_foreach (list, (GFunc) g_object_ref, NULL);
+ list = _mcd_dispatch_operation_dup_channels (context->operation);
while (list != NULL)
{
@@ -2009,8 +2009,7 @@ mcd_dispatcher_context_close_all (McdDispatcherContext *context,
message = "";
}
- list = g_list_copy (context->channels);
- g_list_foreach (list, (GFunc) g_object_ref, NULL);
+ list = _mcd_dispatch_operation_dup_channels (context->operation);
while (list != NULL)
{
@@ -2065,11 +2064,16 @@ mcd_dispatcher_context_unref (McdDispatcherContext * context,
if (context->ref_count == 0)
{
DEBUG ("freeing the context %p", context);
- for (list = context->channels; list != NULL; list = list->next)
+
+ for (list = _mcd_dispatch_operation_dup_channels (context->operation);
+ list != NULL;
+ list = g_list_delete_link (list, list))
{
McdChannel *channel = MCD_CHANNEL (list->data);
+
g_signal_handlers_disconnect_by_func (channel,
G_CALLBACK (on_channel_abort_context), context);
+ g_object_unref (channel);
}
g_signal_handlers_disconnect_by_func (context->operation,
on_operation_finished,
@@ -2122,10 +2126,11 @@ mcd_dispatcher_context_get_dispatcher (McdDispatcherContext * ctx)
McdConnection *
mcd_dispatcher_context_get_connection (McdDispatcherContext *context)
{
- g_return_val_if_fail (context, NULL);
- g_return_val_if_fail (context->channels != NULL, NULL);
+ const GList *channels = mcd_dispatcher_context_get_channels (context);
+
+ g_return_val_if_fail (channels != NULL, NULL);
return MCD_CONNECTION (mcd_mission_get_parent
- (MCD_MISSION (context->channels->data)));
+ (MCD_MISSION (channels->data)));
}
TpConnection *
@@ -2145,9 +2150,9 @@ mcd_dispatcher_context_get_connection_object (McdDispatcherContext * ctx)
McdChannel *
mcd_dispatcher_context_get_channel (McdDispatcherContext * ctx)
{
- g_return_val_if_fail (ctx, 0);
+ const GList *channels = mcd_dispatcher_context_get_channels (ctx);
- return ctx->channels ? MCD_CHANNEL (ctx->channels->data) : NULL;
+ return channels ? MCD_CHANNEL (channels->data) : NULL;
}
/**
@@ -2160,7 +2165,7 @@ const GList *
mcd_dispatcher_context_get_channels (McdDispatcherContext *context)
{
g_return_val_if_fail (context != NULL, NULL);
- return context->channels;
+ return _mcd_dispatch_operation_peek_channels (context->operation);
}
/**
@@ -2174,10 +2179,12 @@ McdChannel *
mcd_dispatcher_context_get_channel_by_type (McdDispatcherContext *context,
GQuark type)
{
- GList *list;
+ const GList *list;
g_return_val_if_fail (context != NULL, NULL);
- for (list = context->channels; list != NULL; list = list->next)
+ for (list = mcd_dispatcher_context_get_channels (context);
+ list != NULL;
+ list = list->next)
{
McdChannel *channel = MCD_CHANNEL (list->data);
@@ -2689,7 +2696,7 @@ find_context_from_channel (McdDispatcher *dispatcher, McdChannel *channel)
{
McdDispatcherContext *context = list->data;
- if (g_list_find (context->channels, channel))
+ if (_mcd_dispatch_operation_has_channel (context->operation, channel))
return context;
}
return NULL;
--
1.5.6.5
More information about the telepathy-commits
mailing list