changeset 15705:6a0b9734a722

The UI can now use the GaimDnsQueryUiOps to handle DNS resolving itself; if this is done, the platform-specific DNS query code won't be used. This will be used in Adium to use an efficient threads-based DNS resolve (since Adium is already multithreaded, this is significantly cheaper than fork()).
author Evan Schoenberg <evan.s@dreskin.net>
date Sun, 25 Feb 2007 18:43:25 +0000
parents 400252586119
children 15123896e5c9
files libpurple/dnsquery.c libpurple/dnsquery.h
diffstat 2 files changed, 124 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/libpurple/dnsquery.c	Sun Feb 25 18:35:08 2007 +0000
+++ b/libpurple/dnsquery.c	Sun Feb 25 18:43:25 2007 +0000
@@ -35,6 +35,8 @@
  * DNS query API
  **************************************************************************/
 
+static GaimDnsQueryUiOps *dns_query_ui_ops = NULL;
+
 typedef struct _GaimDnsQueryResolverProcess GaimDnsQueryResolverProcess;
 
 struct _GaimDnsQueryData {
@@ -114,6 +116,20 @@
 	gaim_dnsquery_destroy(query_data);
 }
 
+static gboolean
+gaim_dnsquery_ui_resolve(GaimDnsQueryData *query_data)
+{
+    GaimDnsQueryUiOps *ops = gaim_dnsquery_get_ui_ops();
+
+    if (ops && ops->resolve_host)
+    {
+        if (ops->resolve_host(query_data, gaim_dnsquery_resolved, gaim_dnsquery_failed))
+            return TRUE;
+    }
+
+	return FALSE;
+}
+
 #if defined(__unix__) || defined(__APPLE__)
 
 /*
@@ -157,7 +173,7 @@
 #endif
 
 #ifdef HAVE_SIGNAL_H
-	gaim_restore_default_signal_handlers();	
+	gaim_restore_default_signal_handlers();
 	signal(SIGTRAP, trap_gdb_bug);
 #endif
 
@@ -455,6 +471,13 @@
 	query_data = queued_requests->data;
 	queued_requests = g_slist_delete_link(queued_requests, queued_requests);
 
+    if (gaim_dnsquery_ui_resolve(query_data))
+    {
+        /* The UI is handling the resolve; we're done */
+    	handle_next_queued_request();
+    	return;
+    }
+
 	/*
 	 * If we have any children, attempt to have them perform the DNS
 	 * query.  If we're able to send the query then resolver will be
@@ -704,6 +727,12 @@
 	query_data = data;
 	query_data->timeout = 0;
 
+    if (gaim_dnsquery_ui_resolve(query_data))
+    {
+        /* The UI is handling the resolve; we're done */
+    	return FALSE;
+    }
+
 	if (inet_aton(query_data->hostname, &sin.sin_addr))
 	{
 		/*
@@ -788,6 +817,12 @@
 	query_data = data;
 	query_data->timeout = 0;
 
+    if (gaim_dnsquery_ui_resolve(query_data))
+    {
+        /* The UI is handling the resolve; we're done */
+    	return FALSE;
+    }
+
 	if (!inet_aton(query_data->hostname, &sin.sin_addr)) {
 		struct hostent *hp;
 		if(!(hp = gethostbyname(query_data->hostname))) {
@@ -846,6 +881,11 @@
 void
 gaim_dnsquery_destroy(GaimDnsQueryData *query_data)
 {
+    GaimDnsQueryUiOps *ops = gaim_dnsquery_get_ui_ops();
+
+    if (ops && ops->destroy)
+        ops->destroy(query_data);
+
 #if defined(__unix__) || defined(__APPLE__)
 	queued_requests = g_slist_remove(queued_requests, query_data);
 
@@ -887,6 +927,36 @@
 	g_free(query_data);
 }
 
+char *
+gaim_dnsquery_get_host(GaimDnsQueryData *query_data)
+{
+	g_return_val_if_fail(query_data != NULL, NULL);
+
+	return query_data->hostname;
+}
+
+int
+gaim_dnsquery_get_port(GaimDnsQueryData *query_data)
+{
+	g_return_val_if_fail(query_data != NULL, NULL);
+
+	return query_data->port;	
+}
+
+void
+gaim_dnsquery_set_ui_ops(GaimDnsQueryUiOps *ops)
+{
+	dns_query_ui_ops = ops;
+}
+
+GaimDnsQueryUiOps *
+gaim_dnsquery_get_ui_ops(void)
+{
+	g_return_val_if_fail(dns_query_ui_ops != NULL, NULL);
+
+	return dns_query_ui_ops;
+}
+
 void
 gaim_dnsquery_init(void)
 {
--- a/libpurple/dnsquery.h	Sun Feb 25 18:35:08 2007 +0000
+++ b/libpurple/dnsquery.h	Sun Feb 25 18:43:25 2007 +0000
@@ -27,6 +27,7 @@
 
 #include <glib.h>
 #include "eventloop.h"
+#include "account.h"
 
 typedef struct _GaimDnsQueryData GaimDnsQueryData;
 
@@ -37,8 +38,26 @@
  */
 typedef void (*GaimDnsQueryConnectFunction)(GSList *hosts, gpointer data, const char *error_message);
 
+/**
+ * Callbacks used by the UI if it handles resolving DNS
+ */
+typedef void  (*GaimDnsQueryResolvedCallback) (GaimDnsQueryData *query_data, GSList *hosts);
+typedef void  (*GaimDnsQueryFailedCallback) (GaimDnsQueryData *query_data, const gchar *error_message);
 
-#include "account.h"
+/**
+ * DNS Request UI operations
+ */
+typedef struct
+{
+    /* If implemented, the UI is responsible for DNS queries */
+    gboolean (*resolve_host)(GaimDnsQueryData *query_data, GaimDnsQueryResolvedCallback resolved_cb, GaimDnsQueryFailedCallback failed_cb);
+    
+    /* After destroy is called, query_data will be feed, so this must
+     * cancel any further use of it the UI would do. Unneeded if 
+     * resolve_host is not implemented.
+     */
+    void (*destroy)(GaimDnsQueryData *query_data);
+} GaimDnsQueryUiOps;
 
 #ifdef __cplusplus
 extern "C" {
@@ -72,6 +91,39 @@
 void gaim_dnsquery_destroy(GaimDnsQueryData *query_data);
 
 /**
+ * Sets the UI operations structure to be used when doing a DNS
+ * resolve.  The UI operations need only be set if the UI wants to
+ * handle the resolve itself; otherwise, leave it as NULL.
+ *
+ * @param ops The UI operations structure.
+ */
+void gaim_dnsquery_set_ui_ops(GaimDnsQueryUiOps *ops);
+
+/**
+ * Returns the UI operations structure to be used when doing a DNS
+ * resolve.
+ *
+ * @return The UI operations structure.
+ */
+GaimDnsQueryUiOps *gaim_dnsquery_get_ui_ops(void);
+
+/**
+ * Get the host associated with a GaimDnsQueryData
+ *
+ * @param query_data The DNS query
+ * @return The host.
+ */
+char *gaim_dnsquery_get_host(GaimDnsQueryData *query_data);
+
+/**
+ * Get the port associated with a GaimDnsQueryData
+ *
+ * @param query_data The DNS query
+ * @return The port.
+ */
+int gaim_dnsquery_get_port(GaimDnsQueryData *query_data);
+
+/**
  * Initializes the DNS query subsystem.
  */
 void gaim_dnsquery_init(void);