]> granicus.if.org Git - curl/commitdiff
added the sharing of DNS cache
authorJean-Philippe Barette-LaPierre <jpbarrette@gmail.com>
Tue, 4 Feb 2003 23:48:46 +0000 (23:48 +0000)
committerJean-Philippe Barette-LaPierre <jpbarrette@gmail.com>
Tue, 4 Feb 2003 23:48:46 +0000 (23:48 +0000)
include/curl/curl.h
lib/Makefile.am
lib/connect.c
lib/ftp.c
lib/hostip.c
lib/hostip.h
lib/share.c
lib/share.h
lib/url.c

index 08630b54ac4f655aa992c0a3020c68ab93ca7db6..04171ba9aa03a0a097c792be4576688a8f1a77cd 100644 (file)
@@ -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;
 
index 7fb16637004540f70ee07c083993676d699f59ee..342a29c46ad506c3846328d0c364d72bc0428ef6 100644 (file)
@@ -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
 
index 8844253265d5bbfc2e9e25f52222675edacf89d9..da0a5b9511f308f49e96ecfbc1e298a75e5af030 100644 (file)
@@ -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
index 8cff5c66a4acb69c92c567d8326353f352d80c04..c7246446c7f48e40a55824ef9b38aa137fc74dc6 100644 (file)
--- a/lib/ftp.c
+++ b/lib/ftp.c
@@ -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
index d5f32fd49d5f31876bea67bb631708d2da117b8c..b5fda2a235b538b8cc0e04a94349d29af23b5dfe 100644 (file)
@@ -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
index 396508e7731d3b7d4f52bd7b0dfe9906ce7dc611..fc1474c395af15d4fdbf156f563d548aeecf380d 100644 (file)
@@ -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);
index dcf7e90bbcccd505a85c651aa9f1e1738e5356c6..8e5ec0ea04ea201c7d025f1428e5a15c550623b8 100644 (file)
@@ -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;
index ea6f2f1ceb684d1805998b31919460c3bd03e913..76e6244d7eaccb186d9d4fc1569d7c67bdc998b5 100644 (file)
 /* 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 */
index 628f3b12a35453f7e286c01b10b9668e9bc4a21c..0836b24ab5519f94596bc8d0e0b4a1ac259a009c 100644 (file)
--- a/lib/url.c
+++ b/lib/url.c
@@ -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 */