Revert "Update to 7.44.0"
[platform/upstream/curl.git] / lib / conncache.c
index b318603..fcfb150 100644 (file)
@@ -6,6 +6,7 @@
  *                             \___|\___/|_| \_\_____|
  *
  * Copyright (C) 2012, Linus Nielsen Feltzing, <linus@haxx.se>
+ * Copyright (C) 2012 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -20,7 +21,7 @@
  *
  ***************************************************************************/
 
-#include "setup.h"
+#include "curl_setup.h"
 
 #include <curl/curl.h>
 
@@ -37,8 +38,6 @@
 /* The last #include file should be: */
 #include "memdebug.h"
 
-#define CONNECTION_HASH_SIZE 97
-
 static void free_bundle_hash_entry(void *freethis)
 {
   struct connectbundle *b = (struct connectbundle *) freethis;
@@ -46,7 +45,7 @@ static void free_bundle_hash_entry(void *freethis)
   Curl_bundle_destroy(b);
 }
 
-struct conncache *Curl_conncache_init(int type)
+struct conncache *Curl_conncache_init(int size)
 {
   struct conncache *connc;
 
@@ -54,7 +53,7 @@ struct conncache *Curl_conncache_init(int type)
   if(!connc)
     return NULL;
 
-  connc->hash = Curl_hash_alloc(CONNECTION_HASH_SIZE, Curl_hash_str,
+  connc->hash = Curl_hash_alloc(size, Curl_hash_str,
                                 Curl_str_key_compare, free_bundle_hash_entry);
 
   if(!connc->hash) {
@@ -62,16 +61,16 @@ struct conncache *Curl_conncache_init(int type)
     return NULL;
   }
 
-  connc->type = type;
-  connc->num_connections = 0;
-
   return connc;
 }
 
 void Curl_conncache_destroy(struct conncache *connc)
 {
-  Curl_hash_destroy(connc->hash);
-  free(connc);
+  if(connc) {
+    Curl_hash_destroy(connc->hash);
+    connc->hash = NULL;
+    free(connc);
+  }
 }
 
 struct connectbundle *Curl_conncache_find_bundle(struct conncache *connc,
@@ -125,26 +124,38 @@ CURLcode Curl_conncache_add_conn(struct conncache *connc,
 {
   CURLcode result;
   struct connectbundle *bundle;
+  struct connectbundle *new_bundle = NULL;
   struct SessionHandle *data = conn->data;
 
   bundle = Curl_conncache_find_bundle(data->state.conn_cache,
                                       conn->host.name);
   if(!bundle) {
-    result = Curl_bundle_create(data, &bundle);
-    if(result != CURLE_OK)
+    result = Curl_bundle_create(data, &new_bundle);
+    if(result)
       return result;
 
     if(!conncache_add_bundle(data->state.conn_cache,
-                             conn->host.name, bundle))
+                             conn->host.name, new_bundle)) {
+      Curl_bundle_destroy(new_bundle);
       return CURLE_OUT_OF_MEMORY;
+    }
+    bundle = new_bundle;
   }
 
   result = Curl_bundle_add_conn(bundle, conn);
-  if(result != CURLE_OK)
+  if(result) {
+    if(new_bundle)
+      conncache_remove_bundle(data->state.conn_cache, new_bundle);
     return result;
+  }
 
+  conn->connection_id = connc->next_connection_id++;
   connc->num_connections++;
 
+  DEBUGF(infof(conn->data, "Added connection %ld. "
+               "The cache now contains %" CURL_FORMAT_CURL_OFF_TU " members\n",
+               conn->connection_id, (curl_off_t) connc->num_connections));
+
   return CURLE_OK;
 }
 
@@ -160,19 +171,26 @@ void Curl_conncache_remove_conn(struct conncache *connc,
     if(bundle->num_connections == 0) {
       conncache_remove_bundle(connc, bundle);
     }
-    connc->num_connections--;
 
-    DEBUGF(infof(conn->data, "The cache now contains %d members\n",
-                 connc->num_connections));
+    if(connc) {
+      connc->num_connections--;
+
+      DEBUGF(infof(conn->data, "The cache now contains %"
+                   CURL_FORMAT_CURL_OFF_TU " members\n",
+                   (curl_off_t) connc->num_connections));
+    }
   }
 }
 
 /* This function iterates the entire connection cache and calls the
    function func() with the connection pointer as the first argument
-   and the supplied 'param' argument as the other */
+   and the supplied 'param' argument as the other,
+
+   Return 0 from func() to continue the loop, return 1 to abort it.
+ */
 void Curl_conncache_foreach(struct conncache *connc,
                             void *param,
-                            void (*func)(void *conn, void *param))
+                            int (*func)(struct connectdata *conn, void *param))
 {
   struct curl_hash_iterator iter;
   struct curl_llist_element *curr;
@@ -186,21 +204,20 @@ void Curl_conncache_foreach(struct conncache *connc,
   he = Curl_hash_next_element(&iter);
   while(he) {
     struct connectbundle *bundle;
-    struct connectdata *conn;
 
     bundle = he->ptr;
+    he = Curl_hash_next_element(&iter);
 
     curr = bundle->conn_list->head;
     while(curr) {
       /* Yes, we need to update curr before calling func(), because func()
          might decide to remove the connection */
-      conn = curr->ptr;
+      struct connectdata *conn = curr->ptr;
       curr = curr->next;
 
-      func(conn, param);
+      if(1 == func(conn, param))
+        return;
     }
-
-    he = Curl_hash_next_element(&iter);
   }
 }
 
@@ -210,7 +227,6 @@ struct connectdata *
 Curl_conncache_find_first_connection(struct conncache *connc)
 {
   struct curl_hash_iterator iter;
-  struct curl_llist_element *curr;
   struct curl_hash_element *he;
   struct connectbundle *bundle;
 
@@ -218,6 +234,7 @@ Curl_conncache_find_first_connection(struct conncache *connc)
 
   he = Curl_hash_next_element(&iter);
   while(he) {
+    struct curl_llist_element *curr;
     bundle = he->ptr;
 
     curr = bundle->conn_list->head;