[Telepathy-commits] [telepathy-mission-control/master] Reinvoke the channel handler with the correct request and user time.

Alberto Mardegan alberto.mardegan at nokia.com
Thu Dec 11 02:24:07 PST 2008


The channel handler must be invoked on the request McdChannel object, so that
the dispatcher will extract the request object path and user action time from
it.
Make sure the channel request is disposed after it has succeeded (if we already
have a McdChannel for that tp channel).
Move the code to McdDispatcher, it seems more fit there.
---
 src/mcd-channel.c    |   31 ++++++++++++++++++++++++++++++-
 src/mcd-channel.h    |    2 ++
 src/mcd-connection.c |   18 ++----------------
 src/mcd-dispatcher.c |   41 ++++++++++++++++++++++++++++++++++++++++-
 src/mcd-dispatcher.h |    6 ++++--
 5 files changed, 78 insertions(+), 20 deletions(-)

diff --git a/src/mcd-channel.c b/src/mcd-channel.c
index 06ad580..c7cb8a9 100644
--- a/src/mcd-channel.c
+++ b/src/mcd-channel.c
@@ -64,6 +64,7 @@ struct _McdChannelPrivate
     guint self_handle_ready : 1;
     guint name_ready : 1;
     guint local_pending_members_ready : 1;
+    guint close_on_dispose : 1;
 
     /* Pending members */
     GArray *pending_local_members;
@@ -588,7 +589,8 @@ _mcd_channel_dispose (GObject * object)
 	return;
 
     priv->is_disposed = TRUE;
-    _mcd_channel_release_tp_channel (MCD_CHANNEL (object), TRUE);
+    _mcd_channel_release_tp_channel (MCD_CHANNEL (object),
+                                     priv->close_on_dispose);
     G_OBJECT_CLASS (mcd_channel_parent_class)->dispose (object);
 }
 
@@ -767,6 +769,7 @@ mcd_channel_init (McdChannel * obj)
     priv->self_handle = INVALID_SELF_HANDLE;
     priv->pending_local_members = g_array_new (FALSE, FALSE,
 					       sizeof (PendingMemberInfo));
+    priv->close_on_dispose = TRUE;
 }
 
 McdChannel *
@@ -1437,3 +1440,29 @@ _mcd_channel_set_request_proxy (McdChannel *channel, McdChannel *source)
                       G_CALLBACK (on_proxied_channel_status_changed), channel);
 }
 
+/*
+ * _mcd_channel_copy_details:
+ * @channel: the #McdChannel.
+ * @source: the #McdChannel from which details are to be copied.
+ *
+ * Copy the #TpProxy and all associated properties from channel @source into
+ * @channel.
+ */
+void
+_mcd_channel_copy_details (McdChannel *channel, McdChannel *source)
+{
+    GHashTable *props;
+
+    g_return_if_fail (MCD_IS_CHANNEL (channel));
+    g_return_if_fail (MCD_IS_CHANNEL (source));
+
+    channel->priv->tp_chan = g_object_ref (source->priv->tp_chan);
+    channel->priv->close_on_dispose = FALSE;
+    /* Once we use the new tp-glib functionality of creating tp channels with
+     * properties the assignment above will copy the immutable properties, too;
+     * but for the time being, we must do it manually */
+    props = _mcd_channel_get_immutable_properties (source);
+    g_hash_table_ref (props);
+    _mcd_channel_set_immutable_properties (channel, props);
+}
+
diff --git a/src/mcd-channel.h b/src/mcd-channel.h
index 724bf3c..8a279ab 100644
--- a/src/mcd-channel.h
+++ b/src/mcd-channel.h
@@ -141,6 +141,8 @@ void _mcd_channel_set_request_use_existing (McdChannel *channel,
                                             gboolean use_existing);
 gboolean _mcd_channel_get_request_use_existing (McdChannel *channel);
 
+G_GNUC_INTERNAL
+void _mcd_channel_copy_details (McdChannel *channel, McdChannel *source);
 void _mcd_channel_set_request_proxy (McdChannel *channel, McdChannel *source);
 
 void _mcd_channel_set_error (McdChannel *channel, GError *error);
diff --git a/src/mcd-connection.c b/src/mcd-connection.c
index be63246..0a79905 100644
--- a/src/mcd-connection.c
+++ b/src/mcd-connection.c
@@ -2190,22 +2190,8 @@ common_request_channel_cb (TpConnection *proxy, gboolean yours,
         existing = find_channel_by_path (connection, channel_path);
         if (existing)
         {
-            /* Two possibilities:
-             *
-             * 1) if @existing is not yet in dispatched state, proxy the
-             * signals from @existing to this request (@channel).
-             *
-             * 2) if @existing is already dispatched, we must re-invoke its
-             * handler
-             */
-            if (mcd_channel_get_status (existing) ==
-                MCD_CHANNEL_STATUS_DISPATCHED)
-            {
-                g_debug ("reinvoking handler on channel %p", existing);
-                _mcd_dispatcher_reinvoke_handler (priv->dispatcher, existing);
-            }
-            g_debug ("channel %p is proxying %p", channel, existing);
-            _mcd_channel_set_request_proxy (channel, existing);
+            _mcd_dispatcher_add_channel_request (priv->dispatcher, existing,
+                                                 channel);
             return;
         }
     }
diff --git a/src/mcd-dispatcher.c b/src/mcd-dispatcher.c
index 5f46dda..436f93a 100644
--- a/src/mcd-dispatcher.c
+++ b/src/mcd-dispatcher.c
@@ -3133,6 +3133,16 @@ mcd_dispatcher_add_filters (McdDispatcher *dispatcher,
                                    filter->user_data);
 }
 
+static void
+on_redispatched_channel_status_changed (McdChannel *channel,
+                                        McdChannelStatus status)
+{
+    if (status == MCD_CHANNEL_STATUS_DISPATCHED)
+    {
+        mcd_mission_abort (MCD_MISSION (channel));
+    }
+}
+
 /*
  * _mcd_dispatcher_reinvoke_handler:
  * @dispatcher: The #McdDispatcher.
@@ -3140,7 +3150,7 @@ mcd_dispatcher_add_filters (McdDispatcher *dispatcher,
  *
  * Re-invoke the channel handler for @channel.
  */
-void
+static void
 _mcd_dispatcher_reinvoke_handler (McdDispatcher *dispatcher,
                                   McdChannel *channel)
 {
@@ -3159,3 +3169,32 @@ _mcd_dispatcher_reinvoke_handler (McdDispatcher *dispatcher,
     /* the context will be unreferenced once it leaves the state machine */
 }
 
+void
+_mcd_dispatcher_add_channel_request (McdDispatcher *dispatcher,
+                                     McdChannel *channel, McdChannel *request)
+{
+    /* if the channel is already dispatched, just reinvoke the handler; if it
+     * is not, @request must mirror the status of @channel */
+    if (mcd_channel_get_status (channel) ==
+        MCD_CHANNEL_STATUS_DISPATCHED)
+    {
+        g_debug ("reinvoking handler on channel %p", channel);
+
+        /* copy the object path and the immutable properties from the
+         * existing channel */
+        _mcd_channel_copy_details (request, channel);
+
+        /* destroy the McdChannel object after it is dispatched */
+        g_signal_connect_after
+            (request, "status-changed",
+             G_CALLBACK (on_redispatched_channel_status_changed), NULL);
+
+        _mcd_dispatcher_reinvoke_handler (dispatcher, request);
+    }
+    else
+    {
+        g_debug ("channel %p is proxying %p", request, channel);
+        _mcd_channel_set_request_proxy (request, channel);
+    }
+}
+
diff --git a/src/mcd-dispatcher.h b/src/mcd-dispatcher.h
index 496e0df..41fc514 100644
--- a/src/mcd-dispatcher.h
+++ b/src/mcd-dispatcher.h
@@ -102,8 +102,10 @@ void _mcd_dispatcher_add_request (McdDispatcher *dispatcher,
                                   McdAccount *account, McdChannel *channel);
 void _mcd_dispatcher_send_channels (McdDispatcher *dispatcher,
                                     GList *channels, gboolean requested);
-void _mcd_dispatcher_reinvoke_handler (McdDispatcher *dispatcher,
-                                       McdChannel *channel);
+G_GNUC_INTERNAL
+void _mcd_dispatcher_add_channel_request (McdDispatcher *dispatcher,
+                                          McdChannel *channel,
+                                          McdChannel *request);
 
 G_END_DECLS
 
-- 
1.5.6.5




More information about the Telepathy-commits mailing list