SoupSessionAsync: fix the idle_run_queue source handling (again)
authorDan Winship <danw@gnome.org>
Sun, 12 Aug 2012 14:32:49 +0000 (10:32 -0400)
committerDan Winship <danw@gnome.org>
Mon, 13 Aug 2012 19:02:24 +0000 (15:02 -0400)
The previous code checked priv->disposed after the session was freed
sometimes...

libsoup/soup-misc-private.h
libsoup/soup-misc.c
libsoup/soup-session-async.c

index 0677fc5..79e73bc 100644 (file)
@@ -41,4 +41,8 @@ SoupURI *soup_socket_get_http_proxy_uri (SoupSocket *sock);
                                           method == SOUP_METHOD_PUT || \
                                           method == SOUP_METHOD_DELETE)
 
+GSource *soup_add_completion_reffed (GMainContext *async_context,
+                                    GSourceFunc   function,
+                                    gpointer      data);
+
 #endif /* SOUP_MISC_PRIVATE_H */
index 8354045..325b587 100644 (file)
@@ -8,6 +8,7 @@
 #include <string.h>
 
 #include "soup-misc.h"
+#include "soup-misc-private.h"
 
 /**
  * SECTION:soup-misc
@@ -112,6 +113,19 @@ soup_add_idle (GMainContext *async_context,
        return source;
 }
 
+GSource *
+soup_add_completion_reffed (GMainContext *async_context,
+                           GSourceFunc   function,
+                           gpointer      data)
+{
+       GSource *source = g_idle_source_new ();
+
+       g_source_set_priority (source, G_PRIORITY_DEFAULT);
+       g_source_set_callback (source, function, data, NULL);
+       g_source_attach (source, async_context);
+       return source;
+}
+
 /**
  * soup_add_completion: (skip)
  * @async_context: (allow-none): the #GMainContext to dispatch the I/O
@@ -132,10 +146,9 @@ GSource *
 soup_add_completion (GMainContext *async_context,
                     GSourceFunc function, gpointer data)
 {
-       GSource *source = g_idle_source_new ();
-       g_source_set_priority (source, G_PRIORITY_DEFAULT);
-       g_source_set_callback (source, function, data, NULL);
-       g_source_attach (source, async_context);
+       GSource *source;
+
+       source = soup_add_completion_reffed (async_context, function, data);
        g_source_unref (source);
        return source;
 }
index 75929ed..0f365f3 100644 (file)
@@ -16,6 +16,7 @@
 #include "soup-session-private.h"
 #include "soup-message-private.h"
 #include "soup-message-queue.h"
+#include "soup-misc-private.h"
 
 /**
  * SECTION:soup-session-async
@@ -37,6 +38,7 @@ G_DEFINE_TYPE (SoupSessionAsync, soup_session_async, SOUP_TYPE_SESSION)
 
 typedef struct {
        SoupSessionAsync *sa;
+       GSList *sources;
        gboolean disposed;
 
 } SoupSessionAsyncPrivate;
@@ -54,8 +56,14 @@ static void
 soup_session_async_dispose (GObject *object)
 {
        SoupSessionAsyncPrivate *priv = SOUP_SESSION_ASYNC_GET_PRIVATE (object);
+       GSList *iter;
 
        priv->disposed = TRUE;
+       for (iter = priv->sources; iter; iter = iter->next) {
+               g_source_destroy (iter->data);
+               g_source_unref (iter->data);
+       }
+       g_clear_pointer (&priv->sources, g_slist_free);
 
        G_OBJECT_CLASS (soup_session_async_parent_class)->dispose (object);
 }
@@ -359,12 +367,17 @@ static gboolean
 idle_run_queue (gpointer user_data)
 {
        SoupSessionAsyncPrivate *priv = user_data;
+       GSource *source;
 
        if (priv->disposed)
                return FALSE;
 
+       source = g_main_current_source ();
+       priv->sources = g_slist_remove (priv->sources, source);
+
        /* Ensure that the source is destroyed before running the queue */
-       g_source_destroy (g_main_current_source ());
+       g_source_destroy (source);
+       g_source_unref (source);
 
        run_queue (priv->sa);
        return FALSE;
@@ -389,7 +402,8 @@ do_idle_run_queue (SoupSession *session)
        if (source)
                return;
 
-       source = soup_add_completion (async_context, idle_run_queue, priv);
+       source = soup_add_completion_reffed (async_context, idle_run_queue, priv);
+       priv->sources = g_slist_prepend (priv->sources, source);
 }
 
 static void