[librest] call: disconnect GCancellable 'cancel' signal



commit 2b363686aa1cbfa2d778a16b813472f1bf309cbf
Author: Alban Crequy <alban crequy collabora co uk>
Date:   Mon Jun 17 15:07:15 2013 +0100

    call: disconnect GCancellable 'cancel' signal
    
    Without this fix, the call object could be freed before any
    cancellation. But the 'cancel' callback should not be executed on a
    freed object.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=702483

 rest/rest-proxy-call-private.h |    3 +++
 rest/rest-proxy-call.c         |   21 +++++++++++++++++----
 2 files changed, 20 insertions(+), 4 deletions(-)
---
diff --git a/rest/rest-proxy-call-private.h b/rest/rest-proxy-call-private.h
index ec7a4be..c915691 100644
--- a/rest/rest-proxy-call-private.h
+++ b/rest/rest-proxy-call-private.h
@@ -47,6 +47,9 @@ struct _RestProxyCallPrivate {
   guint status_code;
   gchar *status_message;
 
+  GCancellable *cancellable;
+  gulong cancel_sig;
+
   RestProxy *proxy;
 
   RestProxyCallAsyncClosure *cur_call_closure;
diff --git a/rest/rest-proxy-call.c b/rest/rest-proxy-call.c
index 3e3474b..97ed185 100644
--- a/rest/rest-proxy-call.c
+++ b/rest/rest-proxy-call.c
@@ -110,6 +110,12 @@ rest_proxy_call_dispose (GObject *object)
 {
   RestProxyCallPrivate *priv = GET_PRIVATE (object);
 
+  if (priv->cancellable)
+    {
+      g_signal_handler_disconnect (priv->cancellable, priv->cancel_sig);
+      g_clear_object (&priv->cancellable);
+    }
+
   if (priv->params)
   {
     rest_params_free (priv->params);
@@ -921,8 +927,6 @@ _call_message_call_completed_cb (SoupSession *session,
   call = REST_PROXY_CALL (
       g_async_result_get_source_object (G_ASYNC_RESULT (result)));
 
-  // FIXME: disconnect cancellable ?
-
   finish_call (call, message, &error);
 
   if (error != NULL)
@@ -973,8 +977,11 @@ rest_proxy_call_invoke_async (RestProxyCall      *call,
                                       user_data, rest_proxy_call_invoke_async);
 
   if (cancellable != NULL)
-    g_signal_connect (cancellable, "cancelled",
-        G_CALLBACK (_call_message_call_cancelled_cb), call);
+    {
+      priv->cancel_sig = g_signal_connect (cancellable, "cancelled",
+          G_CALLBACK (_call_message_call_cancelled_cb), call);
+      priv->cancellable = g_object_ref (cancellable);
+    }
 
   _rest_proxy_queue_message (priv->proxy,
                              message,
@@ -1259,6 +1266,12 @@ rest_proxy_call_cancel (RestProxyCall *call)
   priv = GET_PRIVATE (call);
   closure = priv->cur_call_closure;
 
+  if (priv->cancellable)
+    {
+      g_signal_handler_disconnect (priv->cancellable, priv->cancel_sig);
+      g_clear_object (&priv->cancellable);
+    }
+
   if (closure)
   {
     /* This will cause the _call_message_completed_cb to be fired which will


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