[libsoup] SoupSessionAsync: don't queue idles from dispose()



commit 64bdfe9eb24e219b071a06ae03cec49f15b1b71b
Author: Dan Winship <danw gnome org>
Date:   Mon Feb 13 22:05:43 2012 -0500

    SoupSessionAsync: don't queue idles from dispose()
    
    SoupSession does a soup_session_abort() from dispose(), which had the
    effect in SoupSessionAsync of queueing an idle (to check if new
    messages could be sent now that old connections had been closed). This
    causes problems if the session was disposed from a thread other than
    the one that its GMainContext is running in, which is weird, and also
    incompatible with some garbage-collected runtimes. So fix that.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=667364

 libsoup/soup-session-async.c |   17 +++++++++++++----
 tests/misc-test.c            |   33 +++++++++++++++++++++++++++++++++
 2 files changed, 46 insertions(+), 4 deletions(-)
---
diff --git a/libsoup/soup-session-async.c b/libsoup/soup-session-async.c
index 9baa78e..eaadd58 100644
--- a/libsoup/soup-session-async.c
+++ b/libsoup/soup-session-async.c
@@ -69,13 +69,16 @@ soup_session_async_init (SoupSessionAsync *sa)
 }
 
 static void
-finalize (GObject *object)
+dispose (GObject *object)
 {
 	SoupSessionAsyncPrivate *priv = SOUP_SESSION_ASYNC_GET_PRIVATE (object);
 
-	g_hash_table_destroy (priv->idle_run_queue_sources);
+	if (priv->idle_run_queue_sources) {
+		g_hash_table_destroy (priv->idle_run_queue_sources);
+		priv->idle_run_queue_sources = NULL;
+	}
 
-	G_OBJECT_CLASS (soup_session_async_parent_class)->finalize (object);
+	G_OBJECT_CLASS (soup_session_async_parent_class)->dispose (object);
 }
 
 static void
@@ -94,7 +97,7 @@ soup_session_async_class_init (SoupSessionAsyncClass *soup_session_async_class)
 	session_class->auth_required = auth_required;
 	session_class->kick = kick;
 
-	object_class->finalize = finalize;
+	object_class->dispose = dispose;
 }
 
 
@@ -483,6 +486,9 @@ idle_run_queue (gpointer sa)
 {
 	SoupSessionAsyncPrivate *priv = SOUP_SESSION_ASYNC_GET_PRIVATE (sa);
 
+	if (!priv->idle_run_queue_sources)
+		return FALSE;
+
 	g_hash_table_remove (priv->idle_run_queue_sources,
 			     soup_session_get_async_context (sa));
 	run_queue (sa);
@@ -494,6 +500,9 @@ do_idle_run_queue (SoupSession *session)
 {
 	SoupSessionAsyncPrivate *priv = SOUP_SESSION_ASYNC_GET_PRIVATE (session);
 
+	if (!priv->idle_run_queue_sources)
+		return;
+
 	if (!g_hash_table_lookup (priv->idle_run_queue_sources,
 				  soup_session_get_async_context (session))) {
 		GMainContext *async_context = soup_session_get_async_context (session);
diff --git a/tests/misc-test.c b/tests/misc-test.c
index 321d41f..82d2d73 100644
--- a/tests/misc-test.c
+++ b/tests/misc-test.c
@@ -1272,6 +1272,38 @@ do_ipv6_test (void)
 	soup_test_server_quit_unref (ipv6_server);
 }
 
+static void
+do_idle_on_dispose_test (void)
+{
+	SoupSession *session;
+	SoupMessage *msg;
+	GMainContext *async_context;
+
+	debug_printf (1, "\nTesting SoupSessionAsync dispose behavior\n");
+
+	async_context = g_main_context_new ();
+	session = soup_test_session_new (SOUP_TYPE_SESSION_ASYNC,
+					 SOUP_SESSION_ASYNC_CONTEXT, async_context,
+					 NULL);
+
+	msg = soup_message_new_from_uri ("GET", base_uri);
+	soup_session_send_message (session, msg);
+	g_object_unref (msg);
+
+	while (g_main_context_iteration (async_context, FALSE))
+		;
+
+	g_object_run_dispose (G_OBJECT (session));
+
+	if (g_main_context_iteration (async_context, FALSE)) {
+		debug_printf (1, "  idle was queued!\n");
+		errors++;
+	}
+
+	g_object_unref (session);
+	g_main_context_unref (async_context);
+}
+
 int
 main (int argc, char **argv)
 {
@@ -1311,6 +1343,7 @@ main (int argc, char **argv)
 	do_non_persistent_connection_test ();
 	do_dot_dot_test ();
 	do_ipv6_test ();
+	do_idle_on_dispose_test ();
 
 	soup_uri_free (base_uri);
 	soup_uri_free (ssl_base_uri);



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