From 9281a4f2088428557b9f1a458eb9446ddc2a97f2 Mon Sep 17 00:00:00 2001 From: Dan Winship Date: Sun, 12 Aug 2012 10:32:49 -0400 Subject: [PATCH] SoupSessionAsync: fix the idle_run_queue source handling (again) The previous code checked priv->disposed after the session was freed sometimes... --- libsoup/soup-misc-private.h | 4 ++++ libsoup/soup-misc.c | 21 +++++++++++++++++---- libsoup/soup-session-async.c | 18 ++++++++++++++++-- 3 files changed, 37 insertions(+), 6 deletions(-) diff --git a/libsoup/soup-misc-private.h b/libsoup/soup-misc-private.h index 0677fc5..79e73bc 100644 --- a/libsoup/soup-misc-private.h +++ b/libsoup/soup-misc-private.h @@ -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 */ diff --git a/libsoup/soup-misc.c b/libsoup/soup-misc.c index 8354045..325b587 100644 --- a/libsoup/soup-misc.c +++ b/libsoup/soup-misc.c @@ -8,6 +8,7 @@ #include #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; } diff --git a/libsoup/soup-session-async.c b/libsoup/soup-session-async.c index 75929ed..0f365f3 100644 --- a/libsoup/soup-session-async.c +++ b/libsoup/soup-session-async.c @@ -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 -- 2.7.4