aboutsummaryrefslogtreecommitdiff
path: root/lib/multi.c
diff options
context:
space:
mode:
authorMichael Wallner <mike@php.net>2014-08-20 23:31:53 +0200
committerDaniel Stenberg <daniel@haxx.se>2014-08-31 10:49:40 +0200
commit09b5a99816a24a12f769f61db5f7eafd4bc32795 (patch)
tree1b91304501ae6eed8c832ec140acce4dfceeb4ab /lib/multi.c
parent2434a4e88de35a0c7eced46f010292e2b4bfb851 (diff)
resolve: cache lookup for async resolvers
While waiting for a host resolve, check if the host cache may have gotten the name already (by someone else), for when the same name is resolved by several simultanoues requests. The resolver thread occasionally gets stuck in getaddrinfo() when the DNS or anything else is crappy or slow, so when a host is found in the DNS cache, leave the thread alone and let itself cleanup the mess.
Diffstat (limited to 'lib/multi.c')
-rw-r--r--lib/multi.c26
1 files changed, 25 insertions, 1 deletions
diff --git a/lib/multi.c b/lib/multi.c
index 1e5b3c8df..20fc372fa 100644
--- a/lib/multi.c
+++ b/lib/multi.c
@@ -30,6 +30,7 @@
#include "connect.h"
#include "progress.h"
#include "easyif.h"
+#include "share.h"
#include "multiif.h"
#include "sendf.h"
#include "timeval.h"
@@ -1084,9 +1085,32 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
/* awaiting an asynch name resolve to complete */
{
struct Curl_dns_entry *dns = NULL;
+ struct connectdata *conn = data->easy_conn;
+ int stale;
/* check if we have the name resolved by now */
- data->result = Curl_resolver_is_resolved(data->easy_conn, &dns);
+ if(data->share)
+ Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
+
+ dns = Curl_fetch_addr(conn, conn->host.name, (int)conn->port, &stale);
+
+ if(dns) {
+ dns->inuse++; /* we use it! */
+#ifdef CURLRES_ASYNCH
+ conn->async.dns = dns;
+ conn->async.done = TRUE;
+#endif
+ data->result = CURLRESOLV_RESOLVED;
+ infof(data, "Hostname was found in DNS cache\n");
+ }
+ if(stale)
+ infof(data, "Hostname in DNS cache was stale, zapped\n");
+
+ if(data->share)
+ Curl_share_unlock(data, CURL_LOCK_DATA_DNS);
+
+ if(!dns)
+ data->result = Curl_resolver_is_resolved(data->easy_conn, &dns);
/* Update sockets here, because the socket(s) may have been
closed and the application thus needs to be told, even if it