Commit 640296c9 authored by Daniel Stenberg's avatar Daniel Stenberg
Browse files

connection cache: avoid Curl_hash_alloc()

... by using plain structs instead of pointers for the connection cache,
we can avoid several dynamic allocations that weren't necessary.
parent c4d6f916
Loading
Loading
Loading
Loading
+11 −27
Original line number Diff line number Diff line
@@ -45,32 +45,16 @@ static void free_bundle_hash_entry(void *freethis)
  Curl_bundle_destroy(b);
}

struct conncache *Curl_conncache_init(int size)
int Curl_conncache_init(struct conncache *connc, int size)
{
  struct conncache *connc;

  connc = calloc(1, sizeof(struct conncache));
  if(!connc)
    return NULL;

  connc->hash = Curl_hash_alloc(size, Curl_hash_str,
  return Curl_hash_init(&connc->hash, size, Curl_hash_str,
                        Curl_str_key_compare, free_bundle_hash_entry);

  if(!connc->hash) {
    free(connc);
    return NULL;
  }

  return connc;
}

void Curl_conncache_destroy(struct conncache *connc)
{
  if(connc) {
    Curl_hash_destroy(connc->hash);
    connc->hash = NULL;
    free(connc);
  }
  if(connc)
    Curl_hash_clean(&connc->hash);
}

struct connectbundle *Curl_conncache_find_bundle(struct connectdata *conn,
@@ -81,7 +65,7 @@ struct connectbundle *Curl_conncache_find_bundle(struct connectdata *conn,
  char *hostname = conn->bits.proxy?conn->proxy.name:conn->host.name;

  if(connc)
    bundle = Curl_hash_pick(connc->hash, hostname, strlen(hostname)+1);
    bundle = Curl_hash_pick(&connc->hash, hostname, strlen(hostname)+1);

  return bundle;
}
@@ -92,7 +76,7 @@ static bool conncache_add_bundle(struct conncache *connc,
{
  void *p;

  p = Curl_hash_add(connc->hash, hostname, strlen(hostname)+1, bundle);
  p = Curl_hash_add(&connc->hash, hostname, strlen(hostname)+1, bundle);

  return p?TRUE:FALSE;
}
@@ -106,14 +90,14 @@ static void conncache_remove_bundle(struct conncache *connc,
  if(!connc)
    return;

  Curl_hash_start_iterate(connc->hash, &iter);
  Curl_hash_start_iterate(&connc->hash, &iter);

  he = Curl_hash_next_element(&iter);
  while(he) {
    if(he->ptr == bundle) {
      /* The bundle is destroyed by the hash destructor function,
         free_bundle_hash_entry() */
      Curl_hash_delete(connc->hash, he->key, he->key_len);
      Curl_hash_delete(&connc->hash, he->key, he->key_len);
      return;
    }

@@ -201,7 +185,7 @@ void Curl_conncache_foreach(struct conncache *connc,
  if(!connc)
    return;

  Curl_hash_start_iterate(connc->hash, &iter);
  Curl_hash_start_iterate(&connc->hash, &iter);

  he = Curl_hash_next_element(&iter);
  while(he) {
@@ -232,7 +216,7 @@ Curl_conncache_find_first_connection(struct conncache *connc)
  struct curl_hash_element *he;
  struct connectbundle *bundle;

  Curl_hash_start_iterate(connc->hash, &iter);
  Curl_hash_start_iterate(&connc->hash, &iter);

  he = Curl_hash_next_element(&iter);
  while(he) {
+2 −2
Original line number Diff line number Diff line
@@ -24,13 +24,13 @@
 ***************************************************************************/

struct conncache {
  struct curl_hash *hash;
  struct curl_hash hash;
  size_t num_connections;
  long next_connection_id;
  struct timeval last_cleanup;
};

struct conncache *Curl_conncache_init(int size);
int Curl_conncache_init(struct conncache *, int size);

void Curl_conncache_destroy(struct conncache *connc);

+2 −2
Original line number Diff line number Diff line
@@ -1214,8 +1214,8 @@ curl_socket_t Curl_getconnectinfo(struct SessionHandle *data,
    find.found = FALSE;

    Curl_conncache_foreach(data->multi_easy?
                           data->multi_easy->conn_cache:
                           data->multi->conn_cache, &find, conn_is_conn);
                           &data->multi_easy->conn_cache:
                           &data->multi->conn_cache, &find, conn_is_conn);

    if(!find.found) {
      data->state.lastconnect = NULL;
+7 −9
Original line number Diff line number Diff line
@@ -302,8 +302,7 @@ struct Curl_multi *Curl_multi_handle(int hashsize, /* socket hash */
  if(!multi->sockhash)
    goto error;

  multi->conn_cache = Curl_conncache_init(chashsize);
  if(!multi->conn_cache)
  if(Curl_conncache_init(&multi->conn_cache, chashsize))
    goto error;

  multi->msglist = Curl_llist_alloc(multi_freeamsg);
@@ -320,7 +319,7 @@ struct Curl_multi *Curl_multi_handle(int hashsize, /* socket hash */
    goto error;

  multi->closure_handle->multi = multi;
  multi->closure_handle->state.conn_cache = multi->conn_cache;
  multi->closure_handle->state.conn_cache = &multi->conn_cache;

  multi->max_pipeline_length = 5;

@@ -334,8 +333,7 @@ struct Curl_multi *Curl_multi_handle(int hashsize, /* socket hash */
  multi->sockhash = NULL;
  Curl_hash_destroy(multi->hostcache);
  multi->hostcache = NULL;
  Curl_conncache_destroy(multi->conn_cache);
  multi->conn_cache = NULL;
  Curl_conncache_destroy(&multi->conn_cache);
  Curl_close(multi->closure_handle);
  multi->closure_handle = NULL;
  Curl_llist_destroy(multi->msglist, NULL);
@@ -409,7 +407,7 @@ CURLMcode curl_multi_add_handle(CURLM *multi_handle,
  }

  /* Point to the multi's connection cache */
  data->state.conn_cache = multi->conn_cache;
  data->state.conn_cache = &multi->conn_cache;

  data->state.infilesize = data->set.filesize;

@@ -1832,7 +1830,7 @@ static void close_all_connections(struct Curl_multi *multi)
{
  struct connectdata *conn;

  conn = Curl_conncache_find_first_connection(multi->conn_cache);
  conn = Curl_conncache_find_first_connection(&multi->conn_cache);
  while(conn) {
    SIGPIPE_VARIABLE(pipe_st);
    conn->data = multi->closure_handle;
@@ -1842,7 +1840,7 @@ static void close_all_connections(struct Curl_multi *multi)
    (void)Curl_disconnect(conn, FALSE);
    sigpipe_restore(&pipe_st);

    conn = Curl_conncache_find_first_connection(multi->conn_cache);
    conn = Curl_conncache_find_first_connection(&multi->conn_cache);
  }
}

@@ -1873,7 +1871,7 @@ CURLMcode curl_multi_cleanup(CURLM *multi_handle)
    }

    Curl_hash_destroy(multi->sockhash);
    Curl_conncache_destroy(multi->conn_cache);
    Curl_conncache_destroy(&multi->conn_cache);
    Curl_llist_destroy(multi->msglist, NULL);
    Curl_llist_destroy(multi->pending, NULL);

+3 −1
Original line number Diff line number Diff line
@@ -22,6 +22,8 @@
 *
 ***************************************************************************/

#include "conncache.h"

struct Curl_message {
  /* the 'CURLMsg' is the part that is visible to the external user */
  struct CURLMsg extmsg;
@@ -99,7 +101,7 @@ struct Curl_multi {
  bool pipelining_enabled;

  /* Shared connection cache (bundles)*/
  struct conncache *conn_cache;
  struct conncache conn_cache;

  /* This handle will be used for closing the cached connections in
     curl_multi_cleanup() */
Loading