X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=lib%2Fconncache.c;h=fcfb1501506538eec9a46b74e23a91be43816c13;hb=f7bbc1c9b6a8e2c815d09612b53f453c90d962e0;hp=c712ed7b950a91f0b403ef52b24d4e3e085f7aea;hpb=31368b6eac8092a307849518e912b4c475c0238a;p=platform%2Fupstream%2Fcurl.git diff --git a/lib/conncache.c b/lib/conncache.c index c712ed7..fcfb150 100644 --- a/lib/conncache.c +++ b/lib/conncache.c @@ -6,7 +6,7 @@ * \___|\___/|_| \_\_____| * * Copyright (C) 2012, Linus Nielsen Feltzing, - * Copyright (C) 2012 - 2015, Daniel Stenberg, , et al. + * Copyright (C) 2012 - 2014, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -31,134 +31,66 @@ #include "multiif.h" #include "sendf.h" #include "rawstr.h" +#include "bundles.h" #include "conncache.h" -#include "curl_printf.h" #include "curl_memory.h" /* The last #include file should be: */ #include "memdebug.h" -static void conn_llist_dtor(void *user, void *element) -{ - struct connectdata *data = element; - (void)user; - - data->bundle = NULL; -} - -static CURLcode bundle_create(struct SessionHandle *data, - struct connectbundle **cb_ptr) -{ - (void)data; - DEBUGASSERT(*cb_ptr == NULL); - *cb_ptr = malloc(sizeof(struct connectbundle)); - if(!*cb_ptr) - return CURLE_OUT_OF_MEMORY; - - (*cb_ptr)->num_connections = 0; - (*cb_ptr)->multiuse = BUNDLE_UNKNOWN; - - (*cb_ptr)->conn_list = Curl_llist_alloc((curl_llist_dtor) conn_llist_dtor); - if(!(*cb_ptr)->conn_list) { - Curl_safefree(*cb_ptr); - return CURLE_OUT_OF_MEMORY; - } - return CURLE_OK; -} - -static void bundle_destroy(struct connectbundle *cb_ptr) +static void free_bundle_hash_entry(void *freethis) { - if(!cb_ptr) - return; + struct connectbundle *b = (struct connectbundle *) freethis; - if(cb_ptr->conn_list) { - Curl_llist_destroy(cb_ptr->conn_list, NULL); - cb_ptr->conn_list = NULL; - } - free(cb_ptr); + Curl_bundle_destroy(b); } -/* Add a connection to a bundle */ -static CURLcode bundle_add_conn(struct connectbundle *cb_ptr, - struct connectdata *conn) +struct conncache *Curl_conncache_init(int size) { - if(!Curl_llist_insert_next(cb_ptr->conn_list, cb_ptr->conn_list->tail, conn)) - return CURLE_OUT_OF_MEMORY; - - conn->bundle = cb_ptr; + struct conncache *connc; - cb_ptr->num_connections++; - return CURLE_OK; -} + connc = calloc(1, sizeof(struct conncache)); + if(!connc) + return NULL; -/* Remove a connection from a bundle */ -static int bundle_remove_conn(struct connectbundle *cb_ptr, - struct connectdata *conn) -{ - struct curl_llist_element *curr; + connc->hash = Curl_hash_alloc(size, Curl_hash_str, + Curl_str_key_compare, free_bundle_hash_entry); - curr = cb_ptr->conn_list->head; - while(curr) { - if(curr->ptr == conn) { - Curl_llist_remove(cb_ptr->conn_list, curr, NULL); - cb_ptr->num_connections--; - conn->bundle = NULL; - return 1; /* we removed a handle */ - } - curr = curr->next; + if(!connc->hash) { + free(connc); + return NULL; } - return 0; -} -static void free_bundle_hash_entry(void *freethis) -{ - struct connectbundle *b = (struct connectbundle *) freethis; - - bundle_destroy(b); -} - -int Curl_conncache_init(struct conncache *connc, int size) -{ - return Curl_hash_init(&connc->hash, size, Curl_hash_str, - Curl_str_key_compare, free_bundle_hash_entry); + return connc; } void Curl_conncache_destroy(struct conncache *connc) { - if(connc) - Curl_hash_destroy(&connc->hash); -} - -/* returns an allocated key to find a bundle for this connection */ -static char *hashkey(struct connectdata *conn) -{ - return aprintf("%s:%d", - conn->bits.proxy?conn->proxy.name:conn->host.name, - conn->localport); + if(connc) { + Curl_hash_destroy(connc->hash); + connc->hash = NULL; + free(connc); + } } -/* Look up the bundle with all the connections to the same host this - connectdata struct is setup to use. */ -struct connectbundle *Curl_conncache_find_bundle(struct connectdata *conn, - struct conncache *connc) +struct connectbundle *Curl_conncache_find_bundle(struct conncache *connc, + char *hostname) { struct connectbundle *bundle = NULL; - if(connc) { - char *key = hashkey(conn); - if(key) { - bundle = Curl_hash_pick(&connc->hash, key, strlen(key)); - free(key); - } - } + + if(connc) + bundle = Curl_hash_pick(connc->hash, hostname, strlen(hostname)+1); return bundle; } static bool conncache_add_bundle(struct conncache *connc, - char *key, + char *hostname, struct connectbundle *bundle) { - void *p = Curl_hash_add(&connc->hash, key, strlen(key), bundle); + void *p; + + p = Curl_hash_add(connc->hash, hostname, strlen(hostname)+1, bundle); return p?TRUE:FALSE; } @@ -172,14 +104,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; } @@ -195,31 +127,22 @@ CURLcode Curl_conncache_add_conn(struct conncache *connc, struct connectbundle *new_bundle = NULL; struct SessionHandle *data = conn->data; - bundle = Curl_conncache_find_bundle(conn, data->state.conn_cache); + bundle = Curl_conncache_find_bundle(data->state.conn_cache, + conn->host.name); if(!bundle) { - char *key; - int rc; - - result = bundle_create(data, &new_bundle); + result = Curl_bundle_create(data, &new_bundle); if(result) return result; - key = hashkey(conn); - if(!key) { - bundle_destroy(new_bundle); - return CURLE_OUT_OF_MEMORY; - } - - rc = conncache_add_bundle(data->state.conn_cache, key, new_bundle); - free(key); - if(!rc) { - bundle_destroy(new_bundle); + if(!conncache_add_bundle(data->state.conn_cache, + conn->host.name, new_bundle)) { + Curl_bundle_destroy(new_bundle); return CURLE_OUT_OF_MEMORY; } bundle = new_bundle; } - result = bundle_add_conn(bundle, conn); + result = Curl_bundle_add_conn(bundle, conn); if(result) { if(new_bundle) conncache_remove_bundle(data->state.conn_cache, new_bundle); @@ -244,7 +167,7 @@ void Curl_conncache_remove_conn(struct conncache *connc, /* The bundle pointer can be NULL, since this function can be called due to a failed connection attempt, before being added to a bundle */ if(bundle) { - bundle_remove_conn(bundle, conn); + Curl_bundle_remove_conn(bundle, conn); if(bundle->num_connections == 0) { conncache_remove_bundle(connc, bundle); } @@ -276,7 +199,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) { @@ -307,7 +230,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) {