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),
/* Non-zero value means to use the global dns cache */
CINIT(DNS_USE_GLOBAL_CACHE, LONG, 91),
CURLOPT_LASTENTRY /* the last unusued */
} CURLoption;

View File

@ -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);
}

View File

@ -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;
}
/*

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,
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);

View File

@ -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
*/

View File

@ -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,

View File

@ -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
*/

View File

@ -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 *);

View File

@ -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 */