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:
Sterling Hughes 2002-01-07 20:52:32 +00:00
parent d3299beec7
commit 8d7f402efb
9 changed files with 89 additions and 16 deletions

View File

@ -488,6 +488,9 @@ typedef enum {
*/ */
CINIT(SSLENGINE_DEFAULT, LONG, 90), 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 */ CURLOPT_LASTENTRY /* the last unusued */
} CURLoption; } CURLoption;

View File

@ -141,8 +141,6 @@ CURLcode curl_global_init(long flags)
if (initialized) if (initialized)
return CURLE_OK; return CURLE_OK;
Curl_host_cache_init();
if (flags & CURL_GLOBAL_SSL) if (flags & CURL_GLOBAL_SSL)
Curl_SSL_init(); Curl_SSL_init();
@ -165,8 +163,8 @@ void curl_global_cleanup(void)
if (!initialized) if (!initialized)
return; return;
Curl_host_cache_dtor(); Curl_global_host_cache_dtor();
if (init_flags & CURL_GLOBAL_SSL) if (init_flags & CURL_GLOBAL_SSL)
Curl_SSL_cleanup(); Curl_SSL_cleanup();
@ -235,12 +233,24 @@ CURLcode curl_easy_perform(CURL *curl)
{ {
struct SessionHandle *data = (struct SessionHandle *)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); return Curl_perform(data);
} }
void curl_easy_cleanup(CURL *curl) void curl_easy_cleanup(CURL *curl)
{ {
struct SessionHandle *data = (struct SessionHandle *)curl; struct SessionHandle *data = (struct SessionHandle *)curl;
if (!Curl_global_host_cache_use(data)) {
curl_hash_destroy(data->hostcache);
}
Curl_close(data); Curl_close(data);
} }

View File

@ -255,11 +255,22 @@ curl_hash_clean(curl_hash *h)
h->table = NULL; h->table = NULL;
} }
size_t
curl_hash_count(curl_hash *h)
{
return h->size;
}
void void
curl_hash_destroy(curl_hash *h) curl_hash_destroy(curl_hash *h)
{ {
if (!h) {
return;
}
curl_hash_clean(h); curl_hash_clean(h);
free(h); free(h);
h = NULL;
} }
/* /*

View File

@ -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, int curl_hash_extended_find(curl_hash *h, char *str_key, unsigned int str_key_len,
unsigned long num_key, void **p); unsigned long num_key, void **p);
void curl_hash_apply(curl_hash *h, void *user, void (*cb)(void *, curl_hash_element *)); 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_clean(curl_hash *h);
void curl_hash_destroy(curl_hash *h); void curl_hash_destroy(curl_hash *h);

View File

@ -70,17 +70,27 @@
#endif #endif
static curl_hash hostname_cache; 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, Curl_addrinfo *Curl_resolv(struct SessionHandle *data,
char *hostname, char *hostname,
@ -90,14 +100,15 @@ Curl_addrinfo *Curl_resolv(struct SessionHandle *data,
Curl_addrinfo *addr = NULL; Curl_addrinfo *addr = NULL;
size_t hostname_len = strlen(hostname)+1; 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; return addr;
}
addr = Curl_getaddrinfo(data, hostname, port, bufp); addr = Curl_getaddrinfo(data, hostname, port, bufp);
if (!addr) if (!addr)
return NULL; 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; return addr;
} }
@ -405,3 +416,4 @@ Curl_addrinfo *Curl_getaddrinfo(struct SessionHandle *data,
* vim600: fdm=marker * vim600: fdm=marker
* vim: et sw=2 ts=2 sts=2 tw=78 * vim: et sw=2 ts=2 sts=2 tw=78
*/ */

View File

@ -23,12 +23,17 @@
* $Id$ * $Id$
*****************************************************************************/ *****************************************************************************/
#include "hash.h"
struct addrinfo; struct addrinfo;
struct hostent; struct hostent;
struct SessionHandle; struct SessionHandle;
void Curl_host_cache_init(void); void Curl_global_host_cache_init(void);
void Curl_host_cache_dtor(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, Curl_addrinfo *Curl_resolv(struct SessionHandle *data,
char *hostname, char *hostname,

View File

@ -82,7 +82,8 @@ struct Curl_multi {
struct Curl_message *msgs; struct Curl_message *msgs;
/* amount of messages in the queue */ /* amount of messages in the queue */
int num_msgs; 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; easy=multi->easy.next;
while(easy) { while(easy) {
switch(easy->state) { switch(easy->state) {
case CURLM_STATE_INIT: case CURLM_STATE_INIT:
/* init this transfer. */ /* init this transfer. */
@ -256,6 +256,17 @@ CURLMcode curl_multi_perform(CURLM *multi_handle, int *running_handles)
} }
break; break;
case CURLM_STATE_CONNECT: 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. */ /* Connect. We get a connection identifier filled in. */
easy->result = Curl_connect(easy->easy_handle, &easy->easy_conn); 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; struct Curl_multi *multi=(struct Curl_multi *)multi_handle;
if(GOOD_MULTI_HANDLE(multi)) { if(GOOD_MULTI_HANDLE(multi)) {
multi->type = 0; /* not good anymore */ multi->type = 0; /* not good anymore */
curl_hash_destroy(multi->hostcache);
/* remove all easy handles */ /* remove all easy handles */
free(multi); 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); 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
*/

View File

@ -284,6 +284,15 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...)
va_start(param, option); va_start(param, option);
switch(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: case CURLOPT_SSL_CIPHER_LIST:
/* set a list of cipher we want to use in the SSL connection */ /* set a list of cipher we want to use in the SSL connection */
data->set.ssl.cipher_list = va_arg(param, char *); data->set.ssl.cipher_list = va_arg(param, char *);

View File

@ -27,6 +27,7 @@
#include "setup.h" #include "setup.h"
#include "hostip.h" #include "hostip.h"
#include "hash.h"
#define PORT_FTP 21 #define PORT_FTP 21
#define PORT_TELNET 23 #define PORT_TELNET 23
@ -644,6 +645,8 @@ struct UserDefined {
bool reuse_fresh; /* do not re-use an existing connection */ bool reuse_fresh; /* do not re-use an existing connection */
bool expect100header; /* TRUE if we added Expect: 100-continue */ bool expect100header; /* TRUE if we added Expect: 100-continue */
bool ftp_use_epsv; /* if EPSV is to be attempted or not */ 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 urlstate' instead. */
struct SessionHandle { struct SessionHandle {
curl_hash *hostcache;
struct UserDefined set; /* values set by the libcurl user */ struct UserDefined set; /* values set by the libcurl user */
struct DynamicStatic change; /* possibly modified userdefined data */ struct DynamicStatic change; /* possibly modified userdefined data */