[glib] gio: fix error handling in async case of GProxyAddressEnumerator



commit 8c7025e72320775f915cdd776e09c7cbecd648ac
Author: Dan Winship <danw gnome org>
Date:   Sun Apr 22 15:20:14 2012 -0400

    gio: fix error handling in async case of GProxyAddressEnumerator
    
    In the async case, a failed DNS lookup was causing the proxy
    resolution to bail out immediately, rather than just moving on to the
    next potential proxy (which might not need us to do the DNS lookup
    beforehand). Fix that.

 gio/gproxyaddressenumerator.c |   95 +++++++++++++++++++++++++----------------
 1 files changed, 58 insertions(+), 37 deletions(-)
---
diff --git a/gio/gproxyaddressenumerator.c b/gio/gproxyaddressenumerator.c
index b7bc04d..e4167db 100644
--- a/gio/gproxyaddressenumerator.c
+++ b/gio/gproxyaddressenumerator.c
@@ -69,6 +69,7 @@ struct _GProxyAddressEnumeratorPrivate
   gchar			   *proxy_password;
   gboolean                  supports_hostname;
   GList			   *next_dest_ip;
+  GError                   *last_error;
 
   /* Async attributes */
   GSimpleAsyncResult *simple;
@@ -316,6 +317,13 @@ complete_async (GProxyAddressEnumeratorPrivate *priv)
     }
 
   priv->simple = NULL;
+
+  if (priv->last_error)
+    {
+      g_simple_async_result_take_error (simple, priv->last_error);
+      priv->last_error = NULL;
+    }
+
   g_simple_async_result_complete (simple);
   g_object_unref (simple);
 }
@@ -380,24 +388,60 @@ save_result (GProxyAddressEnumeratorPrivate *priv)
 					     g_object_unref);
 }
 
+static void address_enumerate_cb (GObject      *object,
+				  GAsyncResult *result,
+				  gpointer	user_data);
+
+static void
+next_proxy (GProxyAddressEnumeratorPrivate *priv)
+{
+  if (*priv->next_proxy)
+    {
+      g_object_unref (priv->addr_enum);
+      priv->addr_enum = NULL;
+
+      if (priv->dest_ips)
+	{
+	  g_resolver_free_addresses (priv->dest_ips);
+	  priv->dest_ips = NULL;
+	}
+
+      next_enumerator (priv);
+
+      if (priv->addr_enum)
+	{
+	  g_socket_address_enumerator_next_async (priv->addr_enum,
+						  priv->cancellable,
+						  address_enumerate_cb,
+						  priv);
+	  return;
+	}
+    }
+
+  complete_async (priv);
+}
+
 static void
 dest_hostname_lookup_cb (GObject           *object,
 			 GAsyncResult      *result,
 			 gpointer           user_data)
 {
-  GError *error = NULL;
   GProxyAddressEnumeratorPrivate *priv = user_data;
-  GSimpleAsyncResult *simple = priv->simple;
 
+  g_clear_error (&priv->last_error);
   priv->dest_ips = g_resolver_lookup_by_name_finish (G_RESOLVER (object),
 						     result,
-						     &error);
+						     &priv->last_error);
   if (priv->dest_ips)
-    save_result (priv);
+    {
+      save_result (priv);
+      complete_async (priv);
+    }
   else
-    g_simple_async_result_take_error (simple, error);
-
-  complete_async (priv); 
+    {
+      g_clear_object (&priv->proxy_address);
+      next_proxy (priv);
+    }
 }
 
 static void
@@ -405,14 +449,13 @@ address_enumerate_cb (GObject	   *object,
 		      GAsyncResult *result,
 		      gpointer	    user_data)
 {
-  GError *error = NULL;
   GProxyAddressEnumeratorPrivate *priv = user_data;
-  GSimpleAsyncResult *simple = priv->simple;
 
+  g_clear_error (&priv->last_error);
   priv->proxy_address =
     g_socket_address_enumerator_next_finish (priv->addr_enum,
 					     result,
-					     &error);
+					     &priv->last_error);
   if (priv->proxy_address)
     {
       if (!priv->supports_hostname && !priv->dest_ips)
@@ -429,34 +472,10 @@ address_enumerate_cb (GObject	   *object,
 	}
 
       save_result (priv);
+      complete_async (priv);
     }
-  else if (*priv->next_proxy)
-    {
-      g_object_unref (priv->addr_enum);
-      priv->addr_enum = NULL;
-
-      if (priv->dest_ips)
-	{
-	  g_resolver_free_addresses (priv->dest_ips);
-	  priv->dest_ips = NULL;
-	}
-
-      next_enumerator (priv);
-
-      if (priv->addr_enum)
-	{
-	  g_socket_address_enumerator_next_async (priv->addr_enum,
-						  priv->cancellable,
-						  address_enumerate_cb,
-						  priv);
-	  return;
-	}
-    }
-
-  if (error)
-    g_simple_async_result_take_error (simple, error);
-
-  complete_async (priv); 
+  else
+    next_proxy (priv);
 }
 
 static void
@@ -672,6 +691,8 @@ g_proxy_address_enumerator_finalize (GObject *object)
   if (priv->cancellable)
     g_object_unref (priv->cancellable);
 
+  g_clear_error (&priv->last_error);
+
   G_OBJECT_CLASS (g_proxy_address_enumerator_parent_class)->finalize (object);
 }
 



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