aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/hash.c13
-rw-r--r--lib/multi.c24
2 files changed, 32 insertions, 5 deletions
diff --git a/lib/hash.c b/lib/hash.c
index 32c1d0463..b59e56146 100644
--- a/lib/hash.c
+++ b/lib/hash.c
@@ -208,12 +208,15 @@ Curl_hash_pick(struct curl_hash *h, void *key, size_t key_len)
{
struct curl_llist_element *le;
struct curl_hash_element *he;
- struct curl_llist *l = FETCH_LIST(h, key, key_len);
+ struct curl_llist *l;
- for(le = l->head; le; le = le->next) {
- he = le->ptr;
- if(h->comp_func(he->key, he->key_len, key, key_len)) {
- return he->ptr;
+ if(h) {
+ l = FETCH_LIST(h, key, key_len);
+ for(le = l->head; le; le = le->next) {
+ he = le->ptr;
+ if(h->comp_func(he->key, he->key_len, key, key_len)) {
+ return he->ptr;
+ }
}
}
diff --git a/lib/multi.c b/lib/multi.c
index 6834e68e1..dae1f6b56 100644
--- a/lib/multi.c
+++ b/lib/multi.c
@@ -433,6 +433,7 @@ CURLMcode curl_multi_add_handle(CURLM *multi_handle,
struct Curl_multi *multi = (struct Curl_multi *)multi_handle;
struct SessionHandle *data = (struct SessionHandle *)easy_handle;
struct SessionHandle *new_closure = NULL;
+ struct curl_hash *hostcache = NULL;
/* First, make some basic checks that the CURLM handle is a good handle */
if(!GOOD_MULTI_HANDLE(multi))
@@ -461,11 +462,22 @@ CURLMcode curl_multi_add_handle(CURLM *multi_handle,
return CURLM_OUT_OF_MEMORY;
}
+ /* In case multi handle has no hostcache yet, allocate one */
+ if(!multi->hostcache) {
+ hostcache = Curl_mk_dnscache();
+ if(!hostcache) {
+ free(easy);
+ Curl_llist_destroy(timeoutlist, NULL);
+ return CURLM_OUT_OF_MEMORY;
+ }
+ }
+
/* In case multi handle has no closure_handle yet, allocate
a new easy handle to use when closing cached connections */
if(!multi->closure_handle) {
new_closure = (struct SessionHandle *)curl_easy_init();
if(!new_closure) {
+ Curl_hash_destroy(hostcache);
free(easy);
Curl_llist_destroy(timeoutlist, NULL);
return CURLM_OUT_OF_MEMORY;
@@ -487,6 +499,11 @@ CURLMcode curl_multi_add_handle(CURLM *multi_handle,
multi->closure_handle->state.conn_cache = multi->conn_cache;
}
+ /* In case hostcache has been allocated above,
+ it is associated now with the multi handle. */
+ if(hostcache)
+ multi->hostcache = hostcache;
+
/* Make easy handle use timeout list initialized above */
data->state.timeoutlist = timeoutlist;
timeoutlist = NULL;
@@ -650,6 +667,13 @@ CURLMcode curl_multi_remove_handle(CURLM *multi_handle,
if(easy->easy_handle->dns.hostcachetype == HCACHE_MULTI) {
if(multi->num_easy == 1) {
+ if(easy_owns_conn) {
+ Curl_resolver_cancel(easy->easy_conn);
+ if(easy->easy_conn->dns_entry) {
+ Curl_resolv_unlock(easy->easy_handle, easy->easy_conn->dns_entry);
+ easy->easy_conn->dns_entry = NULL;
+ }
+ }
Curl_hostcache_destroy(easy->easy_handle);
multi->hostcache = NULL;
}