[libsoup] SoupSessionAsync: don't queue idles from dispose()
- From: Dan Winship <danw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libsoup] SoupSessionAsync: don't queue idles from dispose()
- Date: Tue, 14 Feb 2012 03:12:25 +0000 (UTC)
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]