r51840 - in /desktop/unstable/libsoup2.4/debian: changelog patches/ patches/series patches/soup-misc-add-a-GDestroyNotify-to-soup_add_completio.patch patches/soup-session-fix-idle_run_queue-source-handling.patch
smcv at users.alioth.debian.org
smcv at users.alioth.debian.org
Wed Dec 21 17:07:33 UTC 2016
Author: smcv
Date: Wed Dec 21 17:07:32 2016
New Revision: 51840
URL: http://svn.debian.org/wsvn/pkg-gnome/?sc=1&rev=51840
Log:
Add patches from upstream 2.57.1 to make freeing a SoupSession thread-safe
This fixes one of several root causes of ostree test
failures. See #827473 and https://github.com/ostreedev/ostree/issues/601
Added:
desktop/unstable/libsoup2.4/debian/patches/
desktop/unstable/libsoup2.4/debian/patches/series
desktop/unstable/libsoup2.4/debian/patches/soup-misc-add-a-GDestroyNotify-to-soup_add_completio.patch
desktop/unstable/libsoup2.4/debian/patches/soup-session-fix-idle_run_queue-source-handling.patch
Modified:
desktop/unstable/libsoup2.4/debian/changelog
Modified: desktop/unstable/libsoup2.4/debian/changelog
URL: http://svn.debian.org/wsvn/pkg-gnome/desktop/unstable/libsoup2.4/debian/changelog?rev=51840&op=diff
==============================================================================
--- desktop/unstable/libsoup2.4/debian/changelog [utf-8] (original)
+++ desktop/unstable/libsoup2.4/debian/changelog [utf-8] Wed Dec 21 17:07:32 2016
@@ -1,6 +1,10 @@
libsoup2.4 (2.56.0-2) UNRELEASED; urgency=medium
- * NOT RELEASED YET
+ [ Simon McVittie ]
+ * Add patches from upstream 2.57.1 to make freeing a SoupSession
+ thread-safe, fixing one of several root causes of ostree test
+ failures (see #827473 and
+ https://github.com/ostreedev/ostree/issues/601).
-- Michael Biebl <biebl at debian.org> Mon, 19 Sep 2016 19:53:11 +0200
Added: desktop/unstable/libsoup2.4/debian/patches/series
URL: http://svn.debian.org/wsvn/pkg-gnome/desktop/unstable/libsoup2.4/debian/patches/series?rev=51840&op=file
==============================================================================
--- desktop/unstable/libsoup2.4/debian/patches/series (added)
+++ desktop/unstable/libsoup2.4/debian/patches/series [utf-8] Wed Dec 21 17:07:32 2016
@@ -0,0 +1,2 @@
+soup-misc-add-a-GDestroyNotify-to-soup_add_completio.patch
+soup-session-fix-idle_run_queue-source-handling.patch
Added: desktop/unstable/libsoup2.4/debian/patches/soup-misc-add-a-GDestroyNotify-to-soup_add_completio.patch
URL: http://svn.debian.org/wsvn/pkg-gnome/desktop/unstable/libsoup2.4/debian/patches/soup-misc-add-a-GDestroyNotify-to-soup_add_completio.patch?rev=51840&op=file
==============================================================================
--- desktop/unstable/libsoup2.4/debian/patches/soup-misc-add-a-GDestroyNotify-to-soup_add_completio.patch (added)
+++ desktop/unstable/libsoup2.4/debian/patches/soup-misc-add-a-GDestroyNotify-to-soup_add_completio.patch [utf-8] Wed Dec 21 17:07:32 2016
@@ -0,0 +1,93 @@
+From: Dan Winship <danw at gnome.org>
+Date: Thu, 14 Jul 2016 16:54:27 -0400
+Subject: soup-misc: add a GDestroyNotify to soup_add_completion_reffed()
+
+Bug: https://bugzilla.gnome.org/show_bug.cgi?id=768567
+Origin: upstream, 2.57.1, commit:0a6bcb99a04a7224997bb22fd057c47ac88a6399
+---
+ libsoup/soup-message-io.c | 2 +-
+ libsoup/soup-misc-private.h | 7 ++++---
+ libsoup/soup-misc.c | 11 ++++++-----
+ libsoup/soup-session.c | 2 +-
+ 4 files changed, 12 insertions(+), 10 deletions(-)
+
+diff --git a/libsoup/soup-message-io.c b/libsoup/soup-message-io.c
+index f7ae436f..a0a052b7 100644
+--- a/libsoup/soup-message-io.c
++++ b/libsoup/soup-message-io.c
+@@ -1317,7 +1317,7 @@ soup_message_io_unpause (SoupMessage *msg)
+
+ if (!io->unpause_source) {
+ io->unpause_source = soup_add_completion_reffed (io->async_context,
+- io_unpause_internal, msg);
++ io_unpause_internal, msg, NULL);
+ }
+ }
+
+diff --git a/libsoup/soup-misc-private.h b/libsoup/soup-misc-private.h
+index 6171ab82..667bdb06 100644
+--- a/libsoup/soup-misc-private.h
++++ b/libsoup/soup-misc-private.h
+@@ -30,9 +30,10 @@ gboolean soup_uri_is_https (SoupURI *uri, char **aliases);
+ method == SOUP_METHOD_PUT || \
+ method == SOUP_METHOD_DELETE)
+
+-GSource *soup_add_completion_reffed (GMainContext *async_context,
+- GSourceFunc function,
+- gpointer data);
++GSource *soup_add_completion_reffed (GMainContext *async_context,
++ GSourceFunc function,
++ gpointer data,
++ GDestroyNotify dnotify);
+
+ guint soup_message_headers_get_ranges_internal (SoupMessageHeaders *hdrs,
+ goffset total_length,
+diff --git a/libsoup/soup-misc.c b/libsoup/soup-misc.c
+index 92dbdb5d..c583d901 100644
+--- a/libsoup/soup-misc.c
++++ b/libsoup/soup-misc.c
+@@ -118,14 +118,15 @@ soup_add_idle (GMainContext *async_context,
+ }
+
+ GSource *
+-soup_add_completion_reffed (GMainContext *async_context,
+- GSourceFunc function,
+- gpointer data)
++soup_add_completion_reffed (GMainContext *async_context,
++ GSourceFunc function,
++ gpointer data,
++ GDestroyNotify dnotify)
+ {
+ GSource *source = g_idle_source_new ();
+
+ g_source_set_priority (source, G_PRIORITY_DEFAULT);
+- g_source_set_callback (source, function, data, NULL);
++ g_source_set_callback (source, function, data, dnotify);
+ g_source_attach (source, async_context);
+ return source;
+ }
+@@ -152,7 +153,7 @@ soup_add_completion (GMainContext *async_context,
+ {
+ GSource *source;
+
+- source = soup_add_completion_reffed (async_context, function, data);
++ source = soup_add_completion_reffed (async_context, function, data, NULL);
+ g_source_unref (source);
+ return source;
+ }
+diff --git a/libsoup/soup-session.c b/libsoup/soup-session.c
+index 0f025194..c263264d 100644
+--- a/libsoup/soup-session.c
++++ b/libsoup/soup-session.c
+@@ -2321,7 +2321,7 @@ soup_session_real_kick_queue (SoupSession *session)
+ source = g_main_context_find_source_by_user_data (item->async_context, priv);
+ if (!source) {
+ source = soup_add_completion_reffed (item->async_context,
+- idle_run_queue, priv);
++ idle_run_queue, priv, NULL);
+ priv->run_queue_sources = g_slist_prepend (priv->run_queue_sources,
+ source);
+ }
+--
+2.11.0
+
Added: desktop/unstable/libsoup2.4/debian/patches/soup-session-fix-idle_run_queue-source-handling.patch
URL: http://svn.debian.org/wsvn/pkg-gnome/desktop/unstable/libsoup2.4/debian/patches/soup-session-fix-idle_run_queue-source-handling.patch?rev=51840&op=file
==============================================================================
--- desktop/unstable/libsoup2.4/debian/patches/soup-session-fix-idle_run_queue-source-handling.patch (added)
+++ desktop/unstable/libsoup2.4/debian/patches/soup-session-fix-idle_run_queue-source-handling.patch [utf-8] Wed Dec 21 17:07:32 2016
@@ -0,0 +1,200 @@
+From: Dan Winship <danw at gnome.org>
+Date: Thu, 14 Jul 2016 10:33:45 -0400
+Subject: soup-session: fix idle_run_queue() source handling
+
+priv->run_queue_sources was un-thread-safe in multiple ways. Now:
+
+1. We pass idle_run_queue() a GWeakRef to the SoupSession, rather than
+ the SoupSession itself. So now it's not possible for the session to
+ get disposed in another thread while idle_run_queue() is running,
+ and it's safe to let the callback get run even after the session is
+ freed.
+
+2. The idle_run_queue() source is given a GDestroyNotify, so it can
+ clean up the weakref even if the source is destroyed behind
+ the session's back.
+
+3. Since we no longer have to forcibly destroy the sources when the
+ session is destroyed, and we don't have to manually clean up after
+ them if they don't get run, we no longer have to explicitly
+ remember the sources after creating them, and so we don't even need
+ priv->run_queue_sources. However, we do still want to make sure
+ that there's only ever one pending idle_run_queue() source per
+ context (so we don't keep adding more and more if the context isn't
+ currently being run), so we add a new "async_pending" field to
+ SoupMessageQueueItem to keep track of that.
+
+Bug: https://bugzilla.gnome.org/show_bug.cgi?id=768567
+Origin: upstream, 2.57.1, commit:95c4333b203d7ade5ebbfdb4f9681a5258c9e04e
+---
+ libsoup/soup-message-queue.h | 3 +-
+ libsoup/soup-session.c | 70 ++++++++++++++++++++------------------------
+ 2 files changed, 34 insertions(+), 39 deletions(-)
+
+diff --git a/libsoup/soup-message-queue.h b/libsoup/soup-message-queue.h
+index 85012cc4..cfb8d8ad 100644
+--- a/libsoup/soup-message-queue.h
++++ b/libsoup/soup-message-queue.h
+@@ -48,9 +48,10 @@ struct _SoupMessageQueueItem {
+ guint new_api : 1;
+ guint io_started : 1;
+ guint async : 1;
++ guint async_pending : 1;
+ guint conn_is_dedicated : 1;
+ guint priority : 3;
+- guint resend_count : 25;
++ guint resend_count : 5;
+
+ SoupMessageQueueItemState state;
+
+diff --git a/libsoup/soup-session.c b/libsoup/soup-session.c
+index c263264d..ca66089b 100644
+--- a/libsoup/soup-session.c
++++ b/libsoup/soup-session.c
+@@ -93,7 +93,6 @@ static guint soup_host_uri_hash (gconstpointer key);
+ static gboolean soup_host_uri_equal (gconstpointer v1, gconstpointer v2);
+
+ typedef struct {
+- SoupSession *session;
+ gboolean disposed;
+
+ GTlsDatabase *tlsdb;
+@@ -138,7 +137,6 @@ typedef struct {
+
+ GMainContext *async_context;
+ gboolean use_thread_context;
+- GSList *run_queue_sources;
+
+ char **http_aliases, **https_aliases;
+
+@@ -220,8 +218,6 @@ soup_session_init (SoupSession *session)
+ SoupSessionPrivate *priv = SOUP_SESSION_GET_PRIVATE (session);
+ SoupAuthManager *auth_manager;
+
+- priv->session = session;
+-
+ priv->queue = soup_message_queue_new (session);
+
+ g_mutex_init (&priv->conn_lock);
+@@ -309,15 +305,6 @@ soup_session_dispose (GObject *object)
+ {
+ SoupSession *session = SOUP_SESSION (object);
+ SoupSessionPrivate *priv = SOUP_SESSION_GET_PRIVATE (session);
+- GSList *iter;
+-
+- priv->disposed = TRUE;
+-
+- for (iter = priv->run_queue_sources; iter; iter = iter->next) {
+- g_source_destroy (iter->data);
+- g_source_unref (iter->data);
+- }
+- g_clear_pointer (&priv->run_queue_sources, g_slist_free);
+
+ priv->disposed = TRUE;
+ soup_session_abort (session);
+@@ -388,7 +375,7 @@ ensure_socket_props (SoupSession *session)
+ }
+
+ ssl_strict = priv->ssl_strict && (priv->tlsdb != NULL ||
+- SOUP_IS_PLAIN_SESSION (priv->session));
++ SOUP_IS_PLAIN_SESSION (session));
+
+ priv->socket_props = soup_socket_properties_new (priv->async_context,
+ priv->use_thread_context,
+@@ -2074,6 +2061,7 @@ async_run_queue (SoupSession *session)
+ item->async_context != soup_session_get_async_context (session))
+ continue;
+
++ item->async_pending = FALSE;
+ soup_session_process_queue_item (session, item, &should_cleanup, TRUE);
+ }
+
+@@ -2094,22 +2082,25 @@ async_run_queue (SoupSession *session)
+ static gboolean
+ idle_run_queue (gpointer user_data)
+ {
+- SoupSessionPrivate *priv = user_data;
+- GSource *source;
++ GWeakRef *wref = user_data;
++ SoupSession *session;
+
+- if (priv->disposed)
++ session = g_weak_ref_get (wref);
++ if (!session)
+ return FALSE;
+
+- source = g_main_current_source ();
+- priv->run_queue_sources = g_slist_remove (priv->run_queue_sources, source);
++ async_run_queue (session);
++ g_object_unref (session);
++ return FALSE;
++}
+
+- /* Ensure that the source is destroyed before running the queue */
+- g_source_destroy (source);
+- g_source_unref (source);
++static void
++idle_run_queue_dnotify (gpointer user_data)
++{
++ GWeakRef *wref = user_data;
+
+- g_assert (priv->session);
+- async_run_queue (priv->session);
+- return FALSE;
++ g_weak_ref_clear (wref);
++ g_slice_free (GWeakRef, wref);
+ }
+
+ /**
+@@ -2302,32 +2293,35 @@ soup_session_real_kick_queue (SoupSession *session)
+ {
+ SoupSessionPrivate *priv = SOUP_SESSION_GET_PRIVATE (session);
+ SoupMessageQueueItem *item;
++ GHashTable *async_pending;
+ gboolean have_sync_items = FALSE;
+
+ if (priv->disposed)
+ return;
+
++ async_pending = g_hash_table_new (NULL, NULL);
+ for (item = soup_message_queue_first (priv->queue);
+ item;
+ item = soup_message_queue_next (priv->queue, item)) {
+ if (item->async) {
+- GSource *source;
+-
+- /* We use priv rather than session as the
+- * source data, because other parts of libsoup
+- * (or the calling app) may have sources using
+- * the session as the source data.
+- */
+- source = g_main_context_find_source_by_user_data (item->async_context, priv);
+- if (!source) {
+- source = soup_add_completion_reffed (item->async_context,
+- idle_run_queue, priv, NULL);
+- priv->run_queue_sources = g_slist_prepend (priv->run_queue_sources,
+- source);
++ GMainContext *context = item->async_context ? item->async_context : g_main_context_default ();
++
++ if (!g_hash_table_contains (async_pending, context)) {
++ if (!item->async_pending) {
++ GWeakRef *wref = g_slice_new (GWeakRef);
++ GSource *source;
++
++ g_weak_ref_init (wref, session);
++ source = soup_add_completion_reffed (context, idle_run_queue, wref, idle_run_queue_dnotify);
++ g_source_unref (source);
++ }
++ g_hash_table_add (async_pending, context);
+ }
++ item->async_pending = TRUE;
+ } else
+ have_sync_items = TRUE;
+ }
++ g_hash_table_unref (async_pending);
+
+ if (have_sync_items) {
+ g_mutex_lock (&priv->conn_lock);
+--
+2.11.0
+
More information about the pkg-gnome-commits
mailing list