[telepathy-mission-control/master] McdDispatchOperation: track how many observers are pending

Simon McVittie simon.mcvittie at collabora.co.uk
Tue Oct 20 08:47:19 PDT 2009


Holding a reference to the DO for each pending observer is currently
unnecessary, since CTXREF05 keeps the Context alive, and that holds a
reference to the DO. However, it'll become significant as the Context
becomes less important.
---
 src/mcd-dispatch-operation-priv.h |    7 ++++++
 src/mcd-dispatch-operation.c      |   41 +++++++++++++++++++++++++++++++++++++
 src/mcd-dispatcher.c              |   21 +++++-------------
 3 files changed, 54 insertions(+), 15 deletions(-)

diff --git a/src/mcd-dispatch-operation-priv.h b/src/mcd-dispatch-operation-priv.h
index 21bcfc0..aed2d34 100644
--- a/src/mcd-dispatch-operation-priv.h
+++ b/src/mcd-dispatch-operation-priv.h
@@ -109,6 +109,13 @@ G_GNUC_INTERNAL gboolean _mcd_dispatch_operation_is_approved (
 G_GNUC_INTERNAL void _mcd_dispatch_operation_set_approved (
     McdDispatchOperation *self);
 
+G_GNUC_INTERNAL gboolean _mcd_dispatch_operation_has_observers_pending (
+    McdDispatchOperation *self);
+G_GNUC_INTERNAL void _mcd_dispatch_operation_inc_observers_pending (
+    McdDispatchOperation *self);
+G_GNUC_INTERNAL void _mcd_dispatch_operation_dec_observers_pending (
+    McdDispatchOperation *self);
+
 G_END_DECLS
 
 #endif
diff --git a/src/mcd-dispatch-operation.c b/src/mcd-dispatch-operation.c
index cc9e511..12ae3f6 100644
--- a/src/mcd-dispatch-operation.c
+++ b/src/mcd-dispatch-operation.c
@@ -110,8 +110,49 @@ struct _McdDispatchOperationPrivate
      * were pre-approved by being returned as a response to another request,
      * or a client approved processing with arbitrary handlers */
     gboolean approved;
+
+    /* 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. This is a client lock.
+     *
+     * A reference is held for each pending observer (and in the
+     * McdDispatcherContext, one instance of CTXREF05 is held for each). */
+    gsize observers_pending;
 };
 
+gboolean
+_mcd_dispatch_operation_has_observers_pending (McdDispatchOperation *self)
+{
+    g_return_val_if_fail (MCD_IS_DISPATCH_OPERATION (self), FALSE);
+    return (self->priv->observers_pending > 0);
+}
+
+void
+_mcd_dispatch_operation_inc_observers_pending (McdDispatchOperation *self)
+{
+    g_return_if_fail (MCD_IS_DISPATCH_OPERATION (self));
+
+    g_object_ref (self);
+
+    DEBUG ("%" G_GSIZE_FORMAT " -> %" G_GSIZE_FORMAT,
+           self->priv->observers_pending,
+           self->priv->observers_pending + 1);
+    self->priv->observers_pending++;
+}
+
+void
+_mcd_dispatch_operation_dec_observers_pending (McdDispatchOperation *self)
+{
+    g_return_if_fail (MCD_IS_DISPATCH_OPERATION (self));
+    DEBUG ("%" G_GSIZE_FORMAT " -> %" G_GSIZE_FORMAT,
+           self->priv->observers_pending,
+           self->priv->observers_pending - 1);
+    g_return_if_fail (self->priv->observers_pending > 0);
+    self->priv->observers_pending--;
+
+    g_object_unref (self);
+}
+
 enum
 {
     PROP_0,
diff --git a/src/mcd-dispatcher.c b/src/mcd-dispatcher.c
index a7c8356..729a3a8 100644
--- a/src/mcd-dispatcher.c
+++ b/src/mcd-dispatcher.c
@@ -113,13 +113,6 @@ struct _McdDispatcherContext
     GList *channels;
     McdDispatchOperation *operation;
 
-    /* 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. This is a client lock.
-     *
-     * One instance of CTXREF05 is held for each pending observer. */
-    gsize observers_pending;
-
     /* The number of approvers that have not yet returned from
      * AddDispatchOperation. Until they have done so, we can't allow the
      * dispatch operation to finish. This is a client lock.
@@ -902,7 +895,7 @@ static void
 mcd_dispatcher_context_check_client_locks (McdDispatcherContext *context)
 {
     if (!context->invoking_clients &&
-        context->observers_pending == 0 &&
+        !_mcd_dispatch_operation_has_observers_pending (context->operation) &&
         _mcd_dispatch_operation_is_approved (context->operation))
     {
         /* no observers etc. left */
@@ -917,10 +910,7 @@ mcd_dispatcher_context_check_client_locks (McdDispatcherContext *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_dispatch_operation_dec_observers_pending (context->operation);
     mcd_dispatcher_context_check_client_locks (context);
 }
 
@@ -1042,9 +1032,9 @@ mcd_dispatcher_run_observers (McdDispatcherContext *context)
         }
 
         _mcd_dispatch_operation_block_finished (context->operation);
-
-        context->observers_pending++;
+        _mcd_dispatch_operation_inc_observers_pending (context->operation);
         mcd_dispatcher_context_ref (context, "CTXREF05");
+
         DEBUG ("calling ObserveChannels on %s for context %p",
                tp_proxy_get_bus_name (client), context);
         tp_cli_client_observer_call_observe_channels (
@@ -1345,7 +1335,8 @@ on_operation_finished (McdDispatchOperation *operation,
      * this cannot happen until all observers and all approvers have
      * returned from ObserveChannels or AddDispatchOperation, respectively. */
     g_assert (context->approvers_pending == 0);
-    g_assert (context->observers_pending == 0);
+    g_assert (!_mcd_dispatch_operation_has_observers_pending
+              (context->operation));
 
     if (context->channels == NULL)
     {
-- 
1.5.6.5




More information about the telepathy-commits mailing list