Skip to content

Commit

Permalink
SoupSocket: if :use-thread-context, hold a ref on it
Browse files Browse the repository at this point in the history
If :use-thread-context is set on a socket, then hold a ref on the
thread-default GMainContext for the life of the socket. In particular,
this fixes a race condition in the test-utils server code that
sometimes shows up in context-test.

https://bugzilla.gnome.org/show_bug.cgi?id=744862
  • Loading branch information
danwinship committed Feb 28, 2015
1 parent 21a213b commit 55bfb80
Showing 1 changed file with 18 additions and 13 deletions.
31 changes: 18 additions & 13 deletions libsoup/soup-socket.c
Expand Up @@ -309,12 +309,18 @@ soup_socket_set_property (GObject *object, guint prop_id,
priv->ssl_fallback = g_value_get_boolean (value);
break;
case PROP_ASYNC_CONTEXT:
priv->async_context = g_value_get_pointer (value);
if (priv->async_context)
g_main_context_ref (priv->async_context);
if (!priv->use_thread_context) {
priv->async_context = g_value_get_pointer (value);
if (priv->async_context)
g_main_context_ref (priv->async_context);
}
break;
case PROP_USE_THREAD_CONTEXT:
priv->use_thread_context = g_value_get_boolean (value);
if (priv->use_thread_context) {
g_clear_pointer (&priv->async_context, g_main_context_unref);
priv->async_context = g_main_context_ref_thread_default ();
}
break;
case PROP_TIMEOUT:
priv->timeout = g_value_get_uint (value);
Expand All @@ -325,9 +331,14 @@ soup_socket_set_property (GObject *object, guint prop_id,
props = g_value_get_boxed (value);
if (props) {
g_clear_pointer (&priv->async_context, g_main_context_unref);
if (props->async_context)
priv->async_context = g_main_context_ref (props->async_context);
priv->use_thread_context = props->use_thread_context;
if (props->use_thread_context) {
priv->use_thread_context = TRUE;
priv->async_context = g_main_context_ref_thread_default ();
} else {
priv->use_thread_context = FALSE;
if (props->async_context)
priv->async_context = g_main_context_ref (props->async_context);
}

g_clear_object (&priv->proxy_resolver);
if (props->proxy_resolver)
Expand Down Expand Up @@ -1161,20 +1172,14 @@ soup_socket_create_watch (SoupSocketPrivate *priv, GIOCondition cond,
GCancellable *cancellable)
{
GSource *watch;
GMainContext *async_context;

if (cond == G_IO_IN)
watch = g_pollable_input_stream_create_source (G_POLLABLE_INPUT_STREAM (priv->istream), cancellable);
else
watch = g_pollable_output_stream_create_source (G_POLLABLE_OUTPUT_STREAM (priv->ostream), cancellable);
g_source_set_callback (watch, (GSourceFunc)callback, user_data, NULL);

if (priv->use_thread_context)
async_context = g_main_context_get_thread_default ();
else
async_context = priv->async_context;

g_source_attach (watch, async_context);
g_source_attach (watch, priv->async_context);
g_source_unref (watch);

return watch;
Expand Down

0 comments on commit 55bfb80

Please sign in to comment.