[telepathy-mission-control/master] McdDispatcherContext: separate pending observers from other "client locks"
Simon McVittie
simon.mcvittie at collabora.co.uk
Tue Sep 8 06:50:24 PDT 2009
---
src/mcd-dispatcher.c | 43 +++++++++++++++++++++++++++++++------------
1 files changed, 31 insertions(+), 12 deletions(-)
diff --git a/src/mcd-dispatcher.c b/src/mcd-dispatcher.c
index 719ab4e..946c9ea 100644
--- a/src/mcd-dispatcher.c
+++ b/src/mcd-dispatcher.c
@@ -108,11 +108,14 @@ struct _McdDispatcherContext
/* bus names (including the common prefix) in preference order */
GStrv possible_handlers;
+ /* The number of observers that have not yet returned from ObserveChannels.
+ * Until they have done so, we can't allow the dispatch operation to
+ * finish. */
+ gsize observers_pending;
/* This variable is the count of locks that must be removed before handlers
- * can be invoked. Each call to an observer increments this count (and
- * decrements it on return), and for unrequested channels we have an
- * approver lock, too.
- * When the variable gets back to 0, handlers are run. */
+ * can be invoked, for reasons other than invoking observers.
+ * When the variable gets back to 0 and observers_pending is also 0,
+ * handlers are run. */
gint client_locks;
/* Number of approvers that we invoked */
@@ -1007,20 +1010,36 @@ finally:
}
static void
-mcd_dispatcher_context_release_client_lock (McdDispatcherContext *context)
+mcd_dispatcher_context_check_client_locks (McdDispatcherContext *context)
{
- g_return_if_fail (context->client_locks > 0);
- DEBUG ("called on %p, locks = %d", context, context->client_locks);
- context->client_locks--;
- if (context->client_locks == 0)
+ if (context->client_locks == 0 && context->observers_pending == 0)
{
- /* no observers left, let's go on with the dispatching */
+ /* no observers etc. left */
mcd_dispatcher_run_handlers (context);
mcd_dispatcher_context_unref (context, "CTXREF13");
}
}
static void
+mcd_dispatcher_context_release_client_lock (McdDispatcherContext *context)
+{
+ DEBUG ("called on %p, locks = %d", context, context->client_locks);
+ g_return_if_fail (context->client_locks > 0);
+ context->client_locks--;
+ mcd_dispatcher_context_check_client_locks (context);
+}
+
+static void
+mcd_dispatcher_context_release_pending_observer (McdDispatcherContext *context)
+{
+ DEBUG ("called on %p, %" G_GSIZE_FORMAT " pending",
+ context, context->observers_pending);
+ g_return_if_fail (context->observers_pending > 0);
+ context->observers_pending--;
+ mcd_dispatcher_context_check_client_locks (context);
+}
+
+static void
observe_channels_cb (TpClient *proxy, const GError *error,
gpointer user_data, GObject *weak_object)
{
@@ -1038,7 +1057,7 @@ observe_channels_cb (TpClient *proxy, const GError *error,
_mcd_dispatch_operation_unblock_finished (context->operation);
}
- mcd_dispatcher_context_release_client_lock (context);
+ mcd_dispatcher_context_release_pending_observer (context);
}
/* The returned GPtrArray is allocated, but the contents are borrowed. */
@@ -1141,7 +1160,7 @@ mcd_dispatcher_run_observers (McdDispatcherContext *context)
_mcd_dispatch_operation_block_finished (context->operation);
}
- context->client_locks++;
+ context->observers_pending++;
mcd_dispatcher_context_ref (context, "CTXREF05");
DEBUG ("calling ObserveChannels on %s for context %p",
client->name, context);
--
1.5.6.5
More information about the telepathy-commits
mailing list