aboutsummaryrefslogtreecommitdiffstats
path: root/lib/conncache.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/conncache.c')
-rw-r--r--lib/conncache.c100
1 files changed, 51 insertions, 49 deletions
diff --git a/lib/conncache.c b/lib/conncache.c
index cbd3bb1b..d21a00cf 100644
--- a/lib/conncache.c
+++ b/lib/conncache.c
@@ -49,53 +49,51 @@ static void conn_llist_dtor(void *user, void *element)
conn->bundle = NULL;
}
-static CURLcode bundle_create(struct Curl_easy *data,
- struct connectbundle **cb_ptr)
+static CURLcode bundle_create(struct connectbundle **bundlep)
{
- (void)data;
- DEBUGASSERT(*cb_ptr == NULL);
- *cb_ptr = malloc(sizeof(struct connectbundle));
- if(!*cb_ptr)
+ DEBUGASSERT(*bundlep == NULL);
+ *bundlep = malloc(sizeof(struct connectbundle));
+ if(!*bundlep)
return CURLE_OUT_OF_MEMORY;
- (*cb_ptr)->num_connections = 0;
- (*cb_ptr)->multiuse = BUNDLE_UNKNOWN;
+ (*bundlep)->num_connections = 0;
+ (*bundlep)->multiuse = BUNDLE_UNKNOWN;
- Curl_llist_init(&(*cb_ptr)->conn_list, (curl_llist_dtor) conn_llist_dtor);
+ Curl_llist_init(&(*bundlep)->conn_list, (curl_llist_dtor) conn_llist_dtor);
return CURLE_OK;
}
-static void bundle_destroy(struct connectbundle *cb_ptr)
+static void bundle_destroy(struct connectbundle *bundle)
{
- if(!cb_ptr)
+ if(!bundle)
return;
- Curl_llist_destroy(&cb_ptr->conn_list, NULL);
+ Curl_llist_destroy(&bundle->conn_list, NULL);
- free(cb_ptr);
+ free(bundle);
}
/* Add a connection to a bundle */
-static void bundle_add_conn(struct connectbundle *cb_ptr,
+static void bundle_add_conn(struct connectbundle *bundle,
struct connectdata *conn)
{
- Curl_llist_insert_next(&cb_ptr->conn_list, cb_ptr->conn_list.tail, conn,
+ Curl_llist_insert_next(&bundle->conn_list, bundle->conn_list.tail, conn,
&conn->bundle_node);
- conn->bundle = cb_ptr;
- cb_ptr->num_connections++;
+ conn->bundle = bundle;
+ bundle->num_connections++;
}
/* Remove a connection from a bundle */
-static int bundle_remove_conn(struct connectbundle *cb_ptr,
+static int bundle_remove_conn(struct connectbundle *bundle,
struct connectdata *conn)
{
struct curl_llist_element *curr;
- curr = cb_ptr->conn_list.head;
+ curr = bundle->conn_list.head;
while(curr) {
if(curr->ptr == conn) {
- Curl_llist_remove(&cb_ptr->conn_list, curr, NULL);
- cb_ptr->num_connections--;
+ Curl_llist_remove(&bundle->conn_list, curr, NULL);
+ bundle->num_connections--;
conn->bundle = NULL;
return 1; /* we removed a handle */
}
@@ -145,12 +143,15 @@ static void hashkey(struct connectdata *conn, char *buf,
const char *hostname;
long port = conn->remote_port;
+#ifndef CURL_DISABLE_PROXY
if(conn->bits.httpproxy && !conn->bits.tunnel_proxy) {
hostname = conn->http_proxy.host.name;
port = conn->port;
}
- else if(conn->bits.conn_to_host)
- hostname = conn->conn_to_host.name;
+ else
+#endif
+ if(conn->bits.conn_to_host)
+ hostname = conn->conn_to_host.name;
else
hostname = conn->host.name;
@@ -162,20 +163,15 @@ static void hashkey(struct connectdata *conn, char *buf,
msnprintf(buf, len, "%ld%s", port, hostname);
}
-void Curl_conncache_unlock(struct Curl_easy *data)
-{
- CONN_UNLOCK(data);
-}
-
/* Returns number of connections currently held in the connection cache.
Locks/unlocks the cache itself!
*/
size_t Curl_conncache_size(struct Curl_easy *data)
{
size_t num;
- CONN_LOCK(data);
+ CONNCACHE_LOCK(data);
num = data->state.conn_cache->num_conn;
- CONN_UNLOCK(data);
+ CONNCACHE_UNLOCK(data);
return num;
}
@@ -188,7 +184,7 @@ struct connectbundle *Curl_conncache_find_bundle(struct connectdata *conn,
const char **hostp)
{
struct connectbundle *bundle = NULL;
- CONN_LOCK(conn->data);
+ CONNCACHE_LOCK(conn->data);
if(connc) {
char key[HASHKEY_SIZE];
hashkey(conn, key, sizeof(key), hostp);
@@ -235,8 +231,7 @@ CURLcode Curl_conncache_add_conn(struct conncache *connc,
struct connectdata *conn)
{
CURLcode result = CURLE_OK;
- struct connectbundle *bundle;
- struct connectbundle *new_bundle = NULL;
+ struct connectbundle *bundle = NULL;
struct Curl_easy *data = conn->data;
/* *find_bundle() locks the connection cache */
@@ -245,20 +240,19 @@ CURLcode Curl_conncache_add_conn(struct conncache *connc,
int rc;
char key[HASHKEY_SIZE];
- result = bundle_create(data, &new_bundle);
+ result = bundle_create(&bundle);
if(result) {
goto unlock;
}
hashkey(conn, key, sizeof(key), NULL);
- rc = conncache_add_bundle(data->state.conn_cache, key, new_bundle);
+ rc = conncache_add_bundle(data->state.conn_cache, key, bundle);
if(!rc) {
- bundle_destroy(new_bundle);
+ bundle_destroy(bundle);
result = CURLE_OUT_OF_MEMORY;
goto unlock;
}
- bundle = new_bundle;
}
bundle_add_conn(bundle, conn);
@@ -270,15 +264,17 @@ CURLcode Curl_conncache_add_conn(struct conncache *connc,
conn->connection_id, connc->num_conn));
unlock:
- CONN_UNLOCK(data);
+ CONNCACHE_UNLOCK(data);
return result;
}
/*
- * Removes the connectdata object from the connection cache *and* clears the
- * ->data pointer association. Pass TRUE/FALSE in the 'lock' argument
- * depending on if the parent function already holds the lock or not.
+ * Removes the connectdata object from the connection cache, but does *not*
+ * clear the conn->data association. The transfer still owns this connection.
+ *
+ * Pass TRUE/FALSE in the 'lock' argument depending on if the parent function
+ * already holds the lock or not.
*/
void Curl_conncache_remove_conn(struct Curl_easy *data,
struct connectdata *conn, bool lock)
@@ -290,7 +286,7 @@ void Curl_conncache_remove_conn(struct Curl_easy *data,
due to a failed connection attempt, before being added to a bundle */
if(bundle) {
if(lock) {
- CONN_LOCK(data);
+ CONNCACHE_LOCK(data);
}
bundle_remove_conn(bundle, conn);
if(bundle->num_connections == 0)
@@ -301,9 +297,8 @@ void Curl_conncache_remove_conn(struct Curl_easy *data,
DEBUGF(infof(data, "The cache now contains %zu members\n",
connc->num_conn));
}
- conn->data = NULL; /* clear the association */
if(lock) {
- CONN_UNLOCK(data);
+ CONNCACHE_UNLOCK(data);
}
}
}
@@ -332,7 +327,7 @@ bool Curl_conncache_foreach(struct Curl_easy *data,
if(!connc)
return FALSE;
- CONN_LOCK(data);
+ CONNCACHE_LOCK(data);
Curl_hash_start_iterate(&connc->hash, &iter);
he = Curl_hash_next_element(&iter);
@@ -350,12 +345,12 @@ bool Curl_conncache_foreach(struct Curl_easy *data,
curr = curr->next;
if(1 == func(conn, param)) {
- CONN_UNLOCK(data);
+ CONNCACHE_UNLOCK(data);
return TRUE;
}
}
}
- CONN_UNLOCK(data);
+ CONNCACHE_UNLOCK(data);
return FALSE;
}
@@ -494,7 +489,7 @@ Curl_conncache_extract_oldest(struct Curl_easy *data)
now = Curl_now();
- CONN_LOCK(data);
+ CONNCACHE_LOCK(data);
Curl_hash_start_iterate(&connc->hash, &iter);
he = Curl_hash_next_element(&iter);
@@ -531,7 +526,7 @@ Curl_conncache_extract_oldest(struct Curl_easy *data)
connc->num_conn));
conn_candidate->data = data; /* associate! */
}
- CONN_UNLOCK(data);
+ CONNCACHE_UNLOCK(data);
return conn_candidate;
}
@@ -539,6 +534,11 @@ Curl_conncache_extract_oldest(struct Curl_easy *data)
void Curl_conncache_close_all_connections(struct conncache *connc)
{
struct connectdata *conn;
+ char buffer[READBUFFER_MIN + 1];
+ if(!connc->closure_handle)
+ return;
+ connc->closure_handle->state.buffer = buffer;
+ connc->closure_handle->set.buffer_size = READBUFFER_MIN;
conn = conncache_find_first_connection(connc);
while(conn) {
@@ -548,12 +548,14 @@ void Curl_conncache_close_all_connections(struct conncache *connc)
sigpipe_ignore(conn->data, &pipe_st);
/* This will remove the connection from the cache */
connclose(conn, "kill all");
+ Curl_conncache_remove_conn(conn->data, conn, TRUE);
(void)Curl_disconnect(connc->closure_handle, conn, FALSE);
sigpipe_restore(&pipe_st);
conn = conncache_find_first_connection(connc);
}
+ connc->closure_handle->state.buffer = NULL;
if(connc->closure_handle) {
SIGPIPE_VARIABLE(pipe_st);
sigpipe_ignore(connc->closure_handle, &pipe_st);