Commit a386562d authored by Sterling Hughes's avatar Sterling Hughes
Browse files

Prune old hostcache entries with each call...

This can be optimized a tidbit, but this is a start.
parent 2bc84fb1
Loading
Loading
Loading
Loading
+20 −0
Original line number Diff line number Diff line
@@ -249,6 +249,26 @@ curl_hash_clean(curl_hash *h)
}
/* }}} */

/* {{{ void curl_hash_clean_with_criterium (curl_hash *, void *, int (*)(void *, void *))
 */
void
curl_hash_clean_with_criterium(curl_hash *h, void *user, int (*comp)(void *, void *))
{
  curl_llist_element *le;
  int i;

  for (i = 0; i < h->slots; ++i) {
    for (le = CURL_LLIST_HEAD(h->table[i]);
         le != NULL;
         le = CURL_LLIST_NEXT(le)) {
      if (comp(user, ((curl_hash_element *) CURL_LLIST_VALP(le))->ptr)) {
        curl_llist_remove(h->table[i], le, (void *) h);
        --h->size;
      }
    }
  }
}

/* {{{ int curl_hash_count (curl_hash *)
 */
int 
+1 −0
Original line number Diff line number Diff line
@@ -53,6 +53,7 @@ int curl_hash_find(curl_hash *, char *, size_t, void **p);
void curl_hash_apply(curl_hash *h, void *user, void (*cb)(void *, curl_hash_element *));
int curl_hash_count(curl_hash *h);
void curl_hash_clean(curl_hash *h);
void curl_hash_clean_with_criterium(curl_hash *h, void *user, int (*comp)(void *, void *));
void curl_hash_destroy(curl_hash *h);

#define curl_hash_update curl_hash_add
+40 −11
Original line number Diff line number Diff line
@@ -152,6 +152,38 @@ _create_hostcache_id(char *server, int port, ssize_t *entry_len)
  return id;
}

struct _curl_hostcache_prune_data {
  int cache_timeout;
  int now;
};

static int
_curl_hostcache_timestamp_remove(void *datap, void *hc)
{
  struct _curl_hostcache_prune_data *data = 
    (struct _curl_hostcache_prune_data *) datap;
  struct curl_dns_cache_entry *c = (struct curl_dns_cache_entry *) hc;
  
  if (data->now - c->timestamp < data->cache_timeout) {
    return 0;
  }
  
  return 1;
}

static void
_curl_hostcache_prune(curl_hash *hostcache, int cache_timeout, int now)
{
  struct _curl_hostcache_prune_data user;

  user.cache_timeout = cache_timeout;
  user.now = now;
  
  curl_hash_clean_with_criterium(hostcache, 
                                 (void *) &user, 
                                 _curl_hostcache_timestamp_remove);
}

/* Macro to save redundant free'ing of entry_id */
#define _hostcache_return(__v) \
{ \
@@ -175,6 +207,13 @@ Curl_addrinfo *Curl_resolv(struct SessionHandle *data,
    return Curl_getaddrinfo(data, hostname, port, bufp);
  }

  time(&now);

  /* Remove outdated entries from the hostcache */
  _curl_hostcache_prune(data->hostcache, 
                        data->set.dns_cache_timeout, 
                        now);

  /* Create an entry id, based upon the hostname and port */
  entry_len = strlen(hostname);
  entry_id = _create_hostcache_id(hostname, port, &entry_len);
@@ -184,20 +223,10 @@ Curl_addrinfo *Curl_resolv(struct SessionHandle *data,
    return Curl_getaddrinfo(data, hostname, port, bufp);
  }
  
  time(&now);
  /* See if its already in our dns cache */
  if (entry_id && curl_hash_find(data->hostcache, entry_id, entry_len+1, (void **) &p)) {
    /* Do we need to check for a cache timeout? */
    if (data->set.dns_cache_timeout != -1) {
      /* Return if the entry has not timed out */
      if ((now - p->timestamp) < data->set.dns_cache_timeout) {
    _hostcache_return(p->addr);
  }
    }
    else {
      _hostcache_return(p->addr);
    }
  }

  /* Create a new cache entry */
  p = (struct curl_dns_cache_entry *) malloc(sizeof(struct curl_dns_cache_entry));