[empathy] dispatch-operation: fix a race by waiting that TpCall is ready



commit 52bb570645883d3920f4950aa1dca8f6d88b4b32
Author: Guillaume Desmottes <guillaume desmottes collabora co uk>
Date:   Mon Jun 7 12:24:22 2010 +0200

    dispatch-operation: fix a race by waiting that TpCall is ready
    
    The call handler constructor rely on the TpCall to be ready (to fetch the
    EmpathyContact associated with the call). If things are going fast (by
    skipping the approving of the call and handling it right away for example) it
    may no be ready yet.

 libempathy/empathy-dispatch-operation.c |   25 +++++++++++++++++++++++++
 1 files changed, 25 insertions(+), 0 deletions(-)
---
diff --git a/libempathy/empathy-dispatch-operation.c b/libempathy/empathy-dispatch-operation.c
index 68143c5..7843812 100644
--- a/libempathy/empathy-dispatch-operation.c
+++ b/libempathy/empathy-dispatch-operation.c
@@ -458,6 +458,17 @@ empathy_dispatcher_operation_tp_chat_ready_cb (GObject *object,
 }
 
 static void
+call_status_changed_cb (EmpathyTpCall *call,
+    GParamSpec *spec,
+    EmpathyDispatchOperation *self)
+{
+  if (empathy_tp_call_get_status (call) <= EMPATHY_TP_CALL_STATUS_READYING)
+    return;
+
+  channel_wrapper_ready (self);
+}
+
+static void
 empathy_dispatch_operation_channel_ready_cb (TpChannel *channel,
   const GError *error, gpointer user_data)
 {
@@ -495,8 +506,22 @@ empathy_dispatch_operation_channel_ready_cb (TpChannel *channel,
     }
   else if (channel_type == TP_IFACE_QUARK_CHANNEL_TYPE_STREAMED_MEDIA)
     {
+      gboolean requested;
       EmpathyTpCall *call = empathy_tp_call_new (channel);
       priv->channel_wrapper = G_OBJECT (call);
+
+      requested = tp_asv_get_boolean (tp_channel_borrow_immutable_properties (
+            channel), TP_PROP_CHANNEL_REQUESTED, NULL);
+
+      if (!requested &&
+          empathy_tp_call_get_status (call) <= EMPATHY_TP_CALL_STATUS_READYING)
+        {
+          /* For incoming calls, we have to wait that the TpCall is ready as
+           * the call-handler rely on it. */
+          priv->ready_handler = g_signal_connect (call,
+              "notify::status", G_CALLBACK (call_status_changed_cb), self);
+          goto out;
+        }
     }
   else if (channel_type == TP_IFACE_QUARK_CHANNEL_TYPE_FILE_TRANSFER)
     {



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]