[libsoup] soup-address: fix a GMainContext bug
- From: Dan Winship <danw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libsoup] soup-address: fix a GMainContext bug
- Date: Mon, 19 Aug 2013 17:42:43 +0000 (UTC)
commit fe3735f81a8e1bfa5242904a94c30217a5101cbc
Author: Dan Winship <danw gnome org>
Date: Mon Aug 19 13:39:51 2013 -0400
soup-address: fix a GMainContext bug
SoupAddress's GSocketAddressEnumerator implementation was passing the
wrong GMainContext to soup_address_resolve_async(), although it only
ended up affecting the address-is-already-resolved case. Fix this.
Also, remove the async_lookups list from SoupAddressPrivate, and just
make multiple calls to the resolver if there are multiple calls to
soup_address_resolve_async() at once, since that code didn't handle
different GMainContexts correctly.
libsoup/soup-address.c | 111 +++++++++++++++++++++---------------------------
1 files changed, 48 insertions(+), 63 deletions(-)
---
diff --git a/libsoup/soup-address.c b/libsoup/soup-address.c
index d698234..b2d1647 100644
--- a/libsoup/soup-address.c
+++ b/libsoup/soup-address.c
@@ -52,7 +52,6 @@ typedef struct {
const char *protocol;
GMutex lock;
- GSList *async_lookups;
} SoupAddressPrivate;
#define SOUP_ADDRESS_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), SOUP_TYPE_ADDRESS,
SoupAddressPrivate))
@@ -674,55 +673,47 @@ update_name (SoupAddress *addr, const char *name, GError *error)
}
typedef struct {
+ SoupAddress *addr;
SoupAddressCallback callback;
gpointer callback_data;
} SoupAddressResolveAsyncData;
static void
-complete_resolve_async (SoupAddress *addr, guint status)
+complete_resolve_async (SoupAddressResolveAsyncData *res_data, guint status)
{
- SoupAddressPrivate *priv = SOUP_ADDRESS_GET_PRIVATE (addr);
- SoupAddressResolveAsyncData *res_data;
- GSList *lookups, *l;
GSource *current_source;
GMainContext *current_context;
- lookups = priv->async_lookups;
- priv->async_lookups = NULL;
-
- /* Awful hack; to make soup_socket_connect_async() with an
- * non-default async_context work correctly, we need to ensure
- * that the non-default context (which we're now running in)
- * is the thread-default when the callbacks are run...
- */
- current_source = g_main_current_source ();
- if (current_source && !g_source_is_destroyed (current_source))
- current_context = g_source_get_context (current_source);
- else
- current_context = NULL;
- g_main_context_push_thread_default (current_context);
+ if (res_data->callback) {
+ /* Awful hack; to make soup_socket_connect_async()
+ * with an non-default async_context work correctly,
+ * we need to ensure that the non-default context
+ * (which we're now running in) is the thread-default
+ * when the callbacks are run...
+ */
+ current_source = g_main_current_source ();
+ if (current_source && !g_source_is_destroyed (current_source))
+ current_context = g_source_get_context (current_source);
+ else
+ current_context = NULL;
+ g_main_context_push_thread_default (current_context);
- for (l = lookups; l; l = l->next) {
- res_data = l->data;
+ res_data->callback (res_data->addr, status,
+ res_data->callback_data);
- if (res_data->callback) {
- res_data->callback (addr, status,
- res_data->callback_data);
- }
- g_slice_free (SoupAddressResolveAsyncData, res_data);
+ g_main_context_pop_thread_default (current_context);
}
- g_slist_free (lookups);
- g_main_context_pop_thread_default (current_context);
-
- g_object_unref (addr);
+ g_object_unref (res_data->addr);
+ g_slice_free (SoupAddressResolveAsyncData, res_data);
}
static void
lookup_resolved (GObject *source, GAsyncResult *result, gpointer user_data)
{
GResolver *resolver = G_RESOLVER (source);
- SoupAddress *addr = user_data;
+ SoupAddressResolveAsyncData *res_data = user_data;
+ SoupAddress *addr = res_data->addr;
SoupAddressPrivate *priv = SOUP_ADDRESS_GET_PRIVATE (addr);
GError *error = NULL;
guint status;
@@ -748,7 +739,7 @@ lookup_resolved (GObject *source, GAsyncResult *result, gpointer user_data)
g_object_ref (addr);
g_object_set_data (G_OBJECT (addr), "async-resolved-error", error);
- complete_resolve_async (addr, status);
+ complete_resolve_async (res_data, status);
g_object_set_data (G_OBJECT (addr), "async-resolved-error", NULL);
g_object_unref (addr);
@@ -757,9 +748,9 @@ lookup_resolved (GObject *source, GAsyncResult *result, gpointer user_data)
}
static gboolean
-idle_complete_resolve (gpointer addr)
+idle_complete_resolve (gpointer res_data)
{
- complete_resolve_async (addr, SOUP_STATUS_OK);
+ complete_resolve_async (res_data, SOUP_STATUS_OK);
return FALSE;
}
@@ -805,7 +796,6 @@ soup_address_resolve_async (SoupAddress *addr, GMainContext *async_context,
SoupAddressPrivate *priv;
SoupAddressResolveAsyncData *res_data;
GResolver *resolver;
- gboolean already_started;
g_return_if_fail (SOUP_IS_ADDRESS (addr));
priv = SOUP_ADDRESS_GET_PRIVATE (addr);
@@ -821,43 +811,37 @@ soup_address_resolve_async (SoupAddress *addr, GMainContext *async_context,
return;
res_data = g_slice_new0 (SoupAddressResolveAsyncData);
+ res_data->addr = g_object_ref (addr);
res_data->callback = callback;
res_data->callback_data = user_data;
- already_started = priv->async_lookups != NULL;
- priv->async_lookups = g_slist_prepend (priv->async_lookups, res_data);
-
- if (already_started)
- return;
-
- g_object_ref (addr);
-
- if (priv->name && priv->sockaddr) {
- soup_add_completion (async_context, idle_complete_resolve, addr);
- return;
- }
-
- resolver = g_resolver_get_default ();
if (async_context)
g_main_context_push_thread_default (async_context);
- if (priv->name) {
- g_resolver_lookup_by_name_async (resolver, priv->name,
- cancellable,
- lookup_resolved, addr);
- } else {
- GInetAddress *gia;
+ if (priv->name && priv->sockaddr)
+ soup_add_completion (async_context, idle_complete_resolve, res_data);
+ else {
+ resolver = g_resolver_get_default ();
+
+ if (priv->name) {
+ g_resolver_lookup_by_name_async (resolver, priv->name,
+ cancellable,
+ lookup_resolved, res_data);
+ } else {
+ GInetAddress *gia;
+
+ gia = soup_address_make_inet_address (addr);
+ g_resolver_lookup_by_address_async (resolver, gia,
+ cancellable,
+ lookup_resolved, res_data);
+ g_object_unref (gia);
+ }
- gia = soup_address_make_inet_address (addr);
- g_resolver_lookup_by_address_async (resolver, gia,
- cancellable,
- lookup_resolved, addr);
- g_object_unref (gia);
+ g_object_unref (resolver);
}
if (async_context)
g_main_context_pop_thread_default (async_context);
- g_object_unref (resolver);
}
static guint
@@ -1205,8 +1189,9 @@ soup_address_address_enumerator_next_async (GSocketAddressEnumerator *enumerato
task = g_task_new (enumerator, cancellable, callback, user_data);
if (!priv->sockaddr) {
- soup_address_resolve_async (addr_enum->addr, NULL, cancellable,
- got_addresses, task);
+ soup_address_resolve_async (addr_enum->addr,
+ g_main_context_get_thread_default (),
+ cancellable, got_addresses, task);
} else {
g_task_return_pointer (task, next_address (addr_enum), g_object_unref);
g_object_unref (task);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]