Make cach'ing work with threads now, there are now three cases:
- Use a global dns cache (via setting the tentatively named, CURLOPT_DNS_USE_GLOBAL_CACHE option to true) - Use a per-handle dns cache, by default - Use a pooled dns cache when in the "multi" interface
This commit is contained in:
Родитель
d3299beec7
Коммит
8d7f402efb
|
@ -488,6 +488,9 @@ typedef enum {
|
|||
*/
|
||||
CINIT(SSLENGINE_DEFAULT, LONG, 90),
|
||||
|
||||
/* Non-zero value means to use the global dns cache */
|
||||
CINIT(DNS_USE_GLOBAL_CACHE, LONG, 91),
|
||||
|
||||
CURLOPT_LASTENTRY /* the last unusued */
|
||||
} CURLoption;
|
||||
|
||||
|
|
18
lib/easy.c
18
lib/easy.c
|
@ -141,8 +141,6 @@ CURLcode curl_global_init(long flags)
|
|||
if (initialized)
|
||||
return CURLE_OK;
|
||||
|
||||
Curl_host_cache_init();
|
||||
|
||||
if (flags & CURL_GLOBAL_SSL)
|
||||
Curl_SSL_init();
|
||||
|
||||
|
@ -165,8 +163,8 @@ void curl_global_cleanup(void)
|
|||
if (!initialized)
|
||||
return;
|
||||
|
||||
Curl_host_cache_dtor();
|
||||
|
||||
Curl_global_host_cache_dtor();
|
||||
|
||||
if (init_flags & CURL_GLOBAL_SSL)
|
||||
Curl_SSL_cleanup();
|
||||
|
||||
|
@ -235,12 +233,24 @@ CURLcode curl_easy_perform(CURL *curl)
|
|||
{
|
||||
struct SessionHandle *data = (struct SessionHandle *)curl;
|
||||
|
||||
if (!data->hostcache) {
|
||||
if (Curl_global_host_cache_use(data)) {
|
||||
data->hostcache = Curl_global_host_cache_get();
|
||||
}
|
||||
else {
|
||||
data->hostcache = curl_hash_alloc(7, Curl_freeaddrinfo);
|
||||
}
|
||||
}
|
||||
|
||||
return Curl_perform(data);
|
||||
}
|
||||
|
||||
void curl_easy_cleanup(CURL *curl)
|
||||
{
|
||||
struct SessionHandle *data = (struct SessionHandle *)curl;
|
||||
if (!Curl_global_host_cache_use(data)) {
|
||||
curl_hash_destroy(data->hostcache);
|
||||
}
|
||||
Curl_close(data);
|
||||
}
|
||||
|
||||
|
|
11
lib/hash.c
11
lib/hash.c
|
@ -255,11 +255,22 @@ curl_hash_clean(curl_hash *h)
|
|||
h->table = NULL;
|
||||
}
|
||||
|
||||
size_t
|
||||
curl_hash_count(curl_hash *h)
|
||||
{
|
||||
return h->size;
|
||||
}
|
||||
|
||||
void
|
||||
curl_hash_destroy(curl_hash *h)
|
||||
{
|
||||
if (!h) {
|
||||
return;
|
||||
}
|
||||
|
||||
curl_hash_clean(h);
|
||||
free(h);
|
||||
h = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -71,6 +71,7 @@ int curl_hash_extended_delete(curl_hash *h, char *str_key, unsigned int str_key_
|
|||
int curl_hash_extended_find(curl_hash *h, char *str_key, unsigned int str_key_len,
|
||||
unsigned long num_key, void **p);
|
||||
void curl_hash_apply(curl_hash *h, void *user, void (*cb)(void *, curl_hash_element *));
|
||||
size_t curl_hash_count(curl_hash *h);
|
||||
void curl_hash_clean(curl_hash *h);
|
||||
void curl_hash_destroy(curl_hash *h);
|
||||
|
||||
|
|
26
lib/hostip.c
26
lib/hostip.c
|
@ -70,17 +70,27 @@
|
|||
#endif
|
||||
|
||||
static curl_hash hostname_cache;
|
||||
static int host_cache_initialized;
|
||||
|
||||
void Curl_host_cache_init(void)
|
||||
void Curl_global_host_cache_init(void)
|
||||
{
|
||||
curl_hash_init(&hostname_cache, 7, Curl_freeaddrinfo);
|
||||
if (!host_cache_initialized) {
|
||||
curl_hash_init(&hostname_cache, 7, Curl_freeaddrinfo);
|
||||
host_cache_initialized = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void Curl_host_cache_dtor(void)
|
||||
curl_hash *Curl_global_host_cache_get(void)
|
||||
{
|
||||
curl_hash_clean(&hostname_cache);
|
||||
return &hostname_cache;
|
||||
}
|
||||
|
||||
void Curl_global_host_cache_dtor(void)
|
||||
{
|
||||
if (host_cache_initialized) {
|
||||
curl_hash_clean(&hostname_cache);
|
||||
}
|
||||
}
|
||||
|
||||
Curl_addrinfo *Curl_resolv(struct SessionHandle *data,
|
||||
char *hostname,
|
||||
|
@ -90,14 +100,15 @@ Curl_addrinfo *Curl_resolv(struct SessionHandle *data,
|
|||
Curl_addrinfo *addr = NULL;
|
||||
size_t hostname_len = strlen(hostname)+1;
|
||||
|
||||
if (curl_hash_find(&hostname_cache, hostname, hostname_len, (void **) &addr))
|
||||
if (curl_hash_find(data->hostcache, hostname, hostname_len, (void **) &addr)) {
|
||||
return addr;
|
||||
|
||||
}
|
||||
|
||||
addr = Curl_getaddrinfo(data, hostname, port, bufp);
|
||||
if (!addr)
|
||||
return NULL;
|
||||
|
||||
curl_hash_add(&hostname_cache, hostname, hostname_len, (const void *) addr);
|
||||
curl_hash_add(data->hostcache, hostname, hostname_len, (const void *) addr);
|
||||
return addr;
|
||||
}
|
||||
|
||||
|
@ -405,3 +416,4 @@ Curl_addrinfo *Curl_getaddrinfo(struct SessionHandle *data,
|
|||
* vim600: fdm=marker
|
||||
* vim: et sw=2 ts=2 sts=2 tw=78
|
||||
*/
|
||||
|
||||
|
|
|
@ -23,12 +23,17 @@
|
|||
* $Id$
|
||||
*****************************************************************************/
|
||||
|
||||
#include "hash.h"
|
||||
|
||||
struct addrinfo;
|
||||
struct hostent;
|
||||
struct SessionHandle;
|
||||
|
||||
void Curl_host_cache_init(void);
|
||||
void Curl_host_cache_dtor(void);
|
||||
void Curl_global_host_cache_init(void);
|
||||
void Curl_global_host_cache_dtor(void);
|
||||
curl_hash *Curl_global_host_cache_get(void);
|
||||
|
||||
#define Curl_global_host_cache_use(__p) ((__p)->set.global_dns_cache)
|
||||
|
||||
Curl_addrinfo *Curl_resolv(struct SessionHandle *data,
|
||||
char *hostname,
|
||||
|
|
24
lib/multi.c
24
lib/multi.c
|
@ -82,7 +82,8 @@ struct Curl_multi {
|
|||
struct Curl_message *msgs;
|
||||
/* amount of messages in the queue */
|
||||
int num_msgs;
|
||||
|
||||
/* Hostname cache */
|
||||
curl_hash *hostcache;
|
||||
};
|
||||
|
||||
|
||||
|
@ -244,7 +245,6 @@ CURLMcode curl_multi_perform(CURLM *multi_handle, int *running_handles)
|
|||
|
||||
easy=multi->easy.next;
|
||||
while(easy) {
|
||||
|
||||
switch(easy->state) {
|
||||
case CURLM_STATE_INIT:
|
||||
/* init this transfer. */
|
||||
|
@ -256,6 +256,17 @@ CURLMcode curl_multi_perform(CURLM *multi_handle, int *running_handles)
|
|||
}
|
||||
break;
|
||||
case CURLM_STATE_CONNECT:
|
||||
if (Curl_global_host_cache_use(easy->easy_handle)) {
|
||||
easy->easy_handle->hostcache = Curl_global_host_cache_get();
|
||||
}
|
||||
else {
|
||||
if (multi->hostcache == NULL) {
|
||||
multi->hostcache = curl_hash_alloc(7, Curl_freeaddrinfo);
|
||||
}
|
||||
|
||||
easy->easy_handle->hostcache = multi->hostcache;
|
||||
}
|
||||
|
||||
/* Connect. We get a connection identifier filled in. */
|
||||
easy->result = Curl_connect(easy->easy_handle, &easy->easy_conn);
|
||||
|
||||
|
@ -328,7 +339,7 @@ CURLMcode curl_multi_cleanup(CURLM *multi_handle)
|
|||
struct Curl_multi *multi=(struct Curl_multi *)multi_handle;
|
||||
if(GOOD_MULTI_HANDLE(multi)) {
|
||||
multi->type = 0; /* not good anymore */
|
||||
|
||||
curl_hash_destroy(multi->hostcache);
|
||||
/* remove all easy handles */
|
||||
|
||||
free(multi);
|
||||
|
@ -341,3 +352,10 @@ CURLMcode curl_multi_cleanup(CURLM *multi_handle)
|
|||
|
||||
CURLMsg *curl_multi_info_read(CURLM *multi_handle, int *msgs_in_queue);
|
||||
|
||||
/*
|
||||
* local variables:
|
||||
* eval: (load-file "../curl-mode.el")
|
||||
* end:
|
||||
* vim600: fdm=marker
|
||||
* vim: et sw=2 ts=2 sts=2 tw=78
|
||||
*/
|
||||
|
|
|
@ -284,6 +284,15 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...)
|
|||
va_start(param, option);
|
||||
|
||||
switch(option) {
|
||||
case CURLOPT_DNS_USE_GLOBAL_CACHE: {
|
||||
int use_cache = va_arg(param, int);
|
||||
if (use_cache) {
|
||||
Curl_global_host_cache_init();
|
||||
}
|
||||
|
||||
data->set.global_dns_cache = use_cache;
|
||||
}
|
||||
break;
|
||||
case CURLOPT_SSL_CIPHER_LIST:
|
||||
/* set a list of cipher we want to use in the SSL connection */
|
||||
data->set.ssl.cipher_list = va_arg(param, char *);
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
|
||||
#include "setup.h"
|
||||
#include "hostip.h"
|
||||
#include "hash.h"
|
||||
|
||||
#define PORT_FTP 21
|
||||
#define PORT_TELNET 23
|
||||
|
@ -644,6 +645,8 @@ struct UserDefined {
|
|||
bool reuse_fresh; /* do not re-use an existing connection */
|
||||
bool expect100header; /* TRUE if we added Expect: 100-continue */
|
||||
bool ftp_use_epsv; /* if EPSV is to be attempted or not */
|
||||
|
||||
bool global_dns_cache;
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -658,6 +661,7 @@ struct UserDefined {
|
|||
* 'struct urlstate' instead. */
|
||||
|
||||
struct SessionHandle {
|
||||
curl_hash *hostcache;
|
||||
struct UserDefined set; /* values set by the libcurl user */
|
||||
struct DynamicStatic change; /* possibly modified userdefined data */
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче