diff options
author | Jean-Philippe Barette-LaPierre <jpbarrette@gmail.com> | 2003-02-04 23:48:46 +0000 |
---|---|---|
committer | Jean-Philippe Barette-LaPierre <jpbarrette@gmail.com> | 2003-02-04 23:48:46 +0000 |
commit | beb13a1d3e832ae97221ba1d9ad7f9bc262de798 (patch) | |
tree | 4d7a4a247c950e3959b9568d76df29df9d54ba8c | |
parent | fa47138327a98195d0be2c8c2d741cee8763d74d (diff) |
added the sharing of DNS cache
-rw-r--r-- | include/curl/curl.h | 13 | ||||
-rw-r--r-- | lib/Makefile.am | 2 | ||||
-rw-r--r-- | lib/connect.c | 2 | ||||
-rw-r--r-- | lib/ftp.c | 4 | ||||
-rw-r--r-- | lib/hostip.c | 25 | ||||
-rw-r--r-- | lib/hostip.h | 2 | ||||
-rw-r--r-- | lib/share.c | 49 | ||||
-rw-r--r-- | lib/share.h | 17 | ||||
-rw-r--r-- | lib/url.c | 29 |
9 files changed, 121 insertions, 22 deletions
diff --git a/include/curl/curl.h b/include/curl/curl.h index 08630b54a..04171ba9a 100644 --- a/include/curl/curl.h +++ b/include/curl/curl.h @@ -902,10 +902,15 @@ typedef enum { /* Different data locks for a single share */ typedef enum { CURL_LOCK_DATA_NONE = 0, - CURL_LOCK_DATA_COOKIE = 1, - CURL_LOCK_DATA_DNS = 2, - CURL_LOCK_DATA_SSL_SESSION = 3, - CURL_LOCK_DATA_CONNECT = 4, + /* CURL_LOCK_DATA_SHARE is used internaly to say that + * the locking is just made to change the internal state of the share + * itself. + */ + CURL_LOCK_DATA_SHARE, + CURL_LOCK_DATA_COOKIE, + CURL_LOCK_DATA_DNS, + CURL_LOCK_DATA_SSL_SESSION, + CURL_LOCK_DATA_CONNECT, CURL_LOCK_DATA_LAST } curl_lock_data; diff --git a/lib/Makefile.am b/lib/Makefile.am index 7fb166370..342a29c46 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -66,7 +66,7 @@ getpass.c netrc.c telnet.h getinfo.c getinfo.h transfer.c strequal.c \ strequal.h easy.c security.h security.c krb4.c krb4.h memdebug.c \ memdebug.h inet_ntoa_r.h http_chunks.c http_chunks.h strtok.c strtok.h \ connect.c connect.h llist.c llist.h hash.c hash.h multi.c \ -content_encoding.c content_encoding.h share.h +content_encoding.c content_encoding.h share.c share.h noinst_HEADERS = setup.h transfer.h diff --git a/lib/connect.c b/lib/connect.c index 884425326..da0a5b951 100644 --- a/lib/connect.c +++ b/lib/connect.c @@ -248,7 +248,7 @@ static CURLcode bindlocal(struct connectdata *conn, if ( h ) { Curl_addrinfo *addr = h->addr; - Curl_resolv_unlock(h); + Curl_resolv_unlock(data, h); /* we don't need it anymore after this function has returned */ #ifdef ENABLE_IPV6 @@ -1233,7 +1233,7 @@ CURLcode ftp_use_port(struct connectdata *conn) if(h) /* when we return from here, we can forget about this */ - Curl_resolv_unlock(h); + Curl_resolv_unlock(data, h); if ( h || sa_filled_in) { if( (portsock = socket(AF_INET, SOCK_STREAM, 0)) >= 0 ) { @@ -1497,7 +1497,7 @@ CURLcode ftp_use_pasv(struct connectdata *conn, &conninfo, connected); - Curl_resolv_unlock(addr); /* we're done using this address */ + Curl_resolv_unlock(data, addr); /* we're done using this address */ /* * When this is used from the multi interface, this might've returned with diff --git a/lib/hostip.c b/lib/hostip.c index d5f32fd49..b5fda2a23 100644 --- a/lib/hostip.c +++ b/lib/hostip.c @@ -64,6 +64,7 @@ #include "sendf.h" #include "hostip.h" #include "hash.h" +#include "share.h" #define _MPRINTF_REPLACE /* use our functions only */ #include <curl/mprintf.h> @@ -211,6 +212,10 @@ void Curl_scan_cache_used(void *user, void *ptr) #define HOSTCACHE_RETURN(dns) \ { \ free(entry_id); \ + if(data->share) \ + { \ + Curl_share_unlock(data, CURL_LOCK_DATA_DNS); \ + } \ return dns; \ } @@ -245,7 +250,12 @@ struct Curl_dns_entry *Curl_resolv(struct SessionHandle *data, /* If we can't create the entry id, fail */ if (!entry_id) return NULL; - + + if(data->share) + { + Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE); + } + /* See if its already in our dns cache */ dns = Curl_hash_pick(data->hostcache, entry_id, entry_len+1); @@ -284,6 +294,19 @@ struct Curl_dns_entry *Curl_resolv(struct SessionHandle *data, HOSTCACHE_RETURN(dns); } +void Curl_resolv_unlock(struct SessionHandle *data, struct Curl_dns_entry *dns) +{ + if(data->share) + { + Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE); + } + dns->inuse--; + if(data->share) + { + Curl_share_unlock(data, CURL_LOCK_DATA_DNS); + } +} + /* * This is a wrapper function for freeing name information in a protocol * independent way. This takes care of using the appropriate underlaying diff --git a/lib/hostip.h b/lib/hostip.h index 396508e77..fc1474c39 100644 --- a/lib/hostip.h +++ b/lib/hostip.h @@ -59,7 +59,7 @@ struct Curl_dns_entry *Curl_resolv(struct SessionHandle *data, int port); /* unlock a previously resolved dns entry */ -#define Curl_resolv_unlock(dns) dns->inuse-- +void Curl_resolv_unlock(struct SessionHandle *data, struct Curl_dns_entry *dns); /* for debugging purposes only: */ void Curl_scan_cache_used(void *user, void *ptr); diff --git a/lib/share.c b/lib/share.c index dcf7e90bb..8e5ec0ea0 100644 --- a/lib/share.c +++ b/lib/share.c @@ -65,12 +65,53 @@ curl_share_setopt(CURLSH *sh, CURLSHoption option, ...) /* this is a type this share will share */ type = va_arg(param, int); share->specifier |= (1<<type); + switch( type ) + { + case CURL_LOCK_DATA_DNS: + if (!share->hostcache) { + share->hostcache = Curl_hash_alloc(7, Curl_freednsinfo); + } + break; + + case CURL_LOCK_DATA_COOKIE: + break; + + case CURL_LOCK_DATA_SSL_SESSION: + break; + + case CURL_LOCK_DATA_CONNECT: + break; + + default: + return CURLSHE_BAD_OPTION; + } break; case CURLSHOPT_UNSHARE: /* this is a type this share will no longer share */ type = va_arg(param, int); share->specifier &= ~(1<<type); + switch( type ) + { + case CURL_LOCK_DATA_DNS: + if (share->hostcache) { + Curl_hash_destroy(share->hostcache); + share->hostcache = NULL; + } + break; + + case CURL_LOCK_DATA_COOKIE: + break; + + case CURL_LOCK_DATA_SSL_SESSION: + break; + + case CURL_LOCK_DATA_CONNECT: + break; + + default: + return CURLSHE_BAD_OPTION; + } break; case CURLSHOPT_LOCKFUNC: @@ -108,7 +149,7 @@ CURLSHcode curl_share_cleanup(CURLSH *sh) CURLSHcode -Curl_share_acquire_lock(struct SessionHandle *data, curl_lock_data type) +Curl_share_lock(struct SessionHandle *data, curl_lock_data type, curl_lock_access access) { struct Curl_share *share = data->share; @@ -116,8 +157,7 @@ Curl_share_acquire_lock(struct SessionHandle *data, curl_lock_data type) return CURLSHE_INVALID; if(share->specifier & (1<<type)) { - share->lockfunc (data, type, CURL_LOCK_ACCESS_SINGLE, share->clientdata); - share->locked |= (1<<type); + share->lockfunc (data, type, access, share->clientdata); } /* else if we don't share this, pretend successful lock */ @@ -125,7 +165,7 @@ Curl_share_acquire_lock(struct SessionHandle *data, curl_lock_data type) } CURLSHcode -Curl_share_release_lock(struct SessionHandle *data, curl_lock_data type) +Curl_share_unlock(struct SessionHandle *data, curl_lock_data type) { struct Curl_share *share = data->share; @@ -134,7 +174,6 @@ Curl_share_release_lock(struct SessionHandle *data, curl_lock_data type) if(share->specifier & (1<<type)) { share->unlockfunc (data, type, share->clientdata); - share->locked &= ~(1<<type); } return CURLSHE_OK; diff --git a/lib/share.h b/lib/share.h index ea6f2f1ce..76e6244d7 100644 --- a/lib/share.h +++ b/lib/share.h @@ -30,15 +30,24 @@ /* this struct is libcurl-private, don't export details */ struct Curl_share { unsigned int specifier; - unsigned int locked; - unsigned int dirty; + volatile unsigned int dirty; curl_lock_function lockfunc; curl_unlock_function unlockfunc; void *clientdata; + + curl_hash *hostcache; }; -CURLSHcode Curl_share_aquire_lock (struct SessionHandle *, curl_lock_data); -CURLSHcode Curl_share_release_lock (struct SessionHandle *, curl_lock_data); +CURLSHcode Curl_share_lock ( + struct SessionHandle *, + curl_lock_data, + curl_lock_access + ); + +CURLSHcode Curl_share_unlock ( + struct SessionHandle *, + curl_lock_data + ); #endif /* __CURL_SHARE_H */ @@ -1078,10 +1078,33 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) struct Curl_share *set; set = va_arg(param, struct Curl_share *); if(data->share) + { + Curl_share_lock(data, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE); + + /* checking the dns cache stuff */ + if(data->share->hostcache == data->hostcache) + { + data->hostcache = NULL; + } + data->share->dirty--; - + + Curl_share_unlock(data, CURL_LOCK_DATA_SHARE); + } + data->share = set; + + Curl_share_lock(data, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE); + data->share->dirty++; + + if( data->hostcache ) + { + Curl_hash_destroy(data->hostcache); + data->hostcache = data->share->hostcache; + } + + Curl_share_unlock(data, CURL_LOCK_DATA_SHARE); } break; @@ -1518,7 +1541,7 @@ static int handleSock5Proxy( socksreq[6] = ((char*)hp->h_addr_list[0])[2]; socksreq[7] = ((char*)hp->h_addr_list[0])[3]; - Curl_resolv_unlock(dns); /* not used anymore from now on */ + Curl_resolv_unlock(conn->data, dns); /* not used anymore from now on */ } else { failf(conn->data, "Failed to resolve \"%s\" for SOCKS5 connect.", @@ -2901,7 +2924,7 @@ CURLcode Curl_done(struct connectdata *conn) } if(conn->connect_addr) - Curl_resolv_unlock(conn->connect_addr); /* done with this */ + Curl_resolv_unlock(conn->data, conn->connect_addr); /* done with this */ #if defined(MALLOCDEBUG) && defined(AGGRESIVE_TEST) /* scan for DNS cache entries still marked as in use */ |