changeset 14263:d7b40a686355

[gaim-migrate @ 16945] Don't call gethostbyname in a thread because it's not thread-safe. committer: Tailor Script <tailor@pidgin.im>
author Mark Doliner <mark@kingant.net>
date Mon, 21 Aug 2006 05:49:20 +0000
parents baff095b146c
children d171bdecf17b
files libgaim/dnsquery.c
diffstat 1 files changed, 32 insertions(+), 22 deletions(-) [+]
line wrap: on
line diff
--- a/libgaim/dnsquery.c	Mon Aug 21 05:25:44 2006 +0000
+++ b/libgaim/dnsquery.c	Mon Aug 21 05:49:20 2006 +0000
@@ -89,22 +89,17 @@
 	return FALSE;
 }
 
+#ifdef HAVE_GETADDRINFO
 static gpointer
 dns_thread(gpointer data)
 {
 	GaimDnsQueryData *query_data;
-#ifdef HAVE_GETADDRINFO
 	int rc;
 	struct addrinfo hints, *res, *tmp;
 	char servname[20];
-#else
-	struct sockaddr_in sin;
-	struct hostent *hp;
-#endif
 
 	query_data = data;
 
-#ifdef HAVE_GETADDRINFO
 	g_snprintf(servname, sizeof(servname), "%d", query_data->port);
 	memset(&hints,0,sizeof(hints));
 
@@ -129,27 +124,13 @@
 	} else {
 		query_data->error_message = g_strdup_printf(_("Error resolving %s: %s"), query_data->hostname, gai_strerror(rc));
 	}
-#else
-	if ((hp = gethostbyname(query_data->hostname))) {
-		memset(&sin, 0, sizeof(struct sockaddr_in));
-		memcpy(&sin.sin_addr.s_addr, hp->h_addr, hp->h_length);
-		sin.sin_family = hp->h_addrtype;
-		sin.sin_port = htons(query_data->port);
 
-		query_data->hosts = g_slist_append(query_data->hosts,
-				GSIZE_TO_POINTER(sizeof(sin)));
-		query_data->hosts = g_slist_append(query_data->hosts,
-				g_memdup(&sin, sizeof(sin)));
-	} else {
-		query_data->error_message = g_strdup_printf(_("Error resolving %s: %d"), query_data->hostname, h_errno);
-	}
-#endif
-
-	/* back to main thread */
+	/* We're done, tell the main thread to look at our results */
 	g_idle_add(dns_main_thread_cb, query_data);
 
 	return 0;
 }
+#endif
 
 static gboolean
 resolve_host(gpointer data)
@@ -176,6 +157,7 @@
 	}
 	else
 	{
+#ifdef HAVE_GETADDRINFO
 		/*
 		 * Spin off a separate thread to perform the DNS lookup so
 		 * that we don't block the UI.
@@ -190,6 +172,34 @@
 			g_error_free(err);
 			gaim_dnsquery_failed(query_data, message);
 		}
+#else
+		struct sockaddr_in sin;
+		struct hostent *hp;
+
+		/*
+		 * gethostbyname() is not threadsafe, but gethostbyname_r() is a GNU
+		 * extension.  Unfortunately this means that we'll have to do a
+		 * blocking DNS query for systems without GETADDRINFO.  Fortunately
+		 * this should be a very small number of systems.
+		 */
+
+		if ((hp = gethostbyname(query_data->hostname))) {
+			memset(&sin, 0, sizeof(struct sockaddr_in));
+			memcpy(&sin.sin_addr.s_addr, hp->h_addr, hp->h_length);
+			sin.sin_family = hp->h_addrtype;
+			sin.sin_port = htons(query_data->port);
+
+			query_data->hosts = g_slist_append(query_data->hosts,
+					GSIZE_TO_POINTER(sizeof(sin)));
+			query_data->hosts = g_slist_append(query_data->hosts,
+					g_memdup(&sin, sizeof(sin)));
+		} else {
+			query_data->error_message = g_strdup_printf(_("Error resolving %s: %d"), query_data->hostname, h_errno);
+		}
+
+		/* We're done! */
+		dns_main_thread(query_data);
+#endif
 	}
 
 	return FALSE;