mirror of
https://github.com/curl/curl.git
synced 2026-08-24 23:53:44 +03:00
conncache: apply multi limits to transfers using a shared pool
- Determine max host and total connection limits from the transfer's own multi handle and test that it works for shared connections. Prior to this change, sincedf67269(precedes 8.13.0), Curl_cpool_check_limits() took the limits from the multi handle that owns the pool. A share-owned pool is not owned by any multi, so the limit check always passed. Prior todf67269the limits came from the transfer's own multi handle. Fixes https://github.com/curl/curl/issues/22265 Closes https://github.com/curl/curl/pull/22266
This commit is contained in:
parent
6bad3db3d5
commit
02214d98f7
5 changed files with 51 additions and 23 deletions
|
|
@ -367,6 +367,22 @@ static struct connectdata *cpool_get_oldest_idle(struct cpool *cpool,
|
|||
return oldest_idle;
|
||||
}
|
||||
|
||||
/* Evict an idle connection to make room in the pool. A pool owned by
|
||||
* a share has no multi that could perform a controlled shutdown of the
|
||||
* connection; terminate it right away. Otherwise, hand it to the
|
||||
* transfer's multi for shutdown. Expects the pool to be locked. */
|
||||
static void cpool_evict_conn(struct cpool *cpool,
|
||||
struct Curl_easy *data,
|
||||
struct connectdata *conn)
|
||||
{
|
||||
if(cpool->share) {
|
||||
cpool_remove_conn(cpool, conn);
|
||||
Curl_cshutdn_terminate(cpool->idata, conn, TRUE);
|
||||
}
|
||||
else
|
||||
Curl_conn_terminate(data, conn, FALSE);
|
||||
}
|
||||
|
||||
int Curl_cpool_check_limits(struct Curl_easy *data,
|
||||
struct connectdata *conn)
|
||||
{
|
||||
|
|
@ -380,9 +396,10 @@ int Curl_cpool_check_limits(struct Curl_easy *data,
|
|||
if(!cpool)
|
||||
return CPOOL_LIMIT_OK;
|
||||
|
||||
if(cpool->idata->multi) {
|
||||
dest_limit = cpool->idata->multi->max_host_connections;
|
||||
total_limit = cpool->idata->multi->max_total_connections;
|
||||
/* multi determines the limits, no matter who owns the pool */
|
||||
if(data->multi) {
|
||||
dest_limit = data->multi->max_host_connections;
|
||||
total_limit = data->multi->max_total_connections;
|
||||
}
|
||||
|
||||
if(!dest_limit && !total_limit)
|
||||
|
|
@ -416,13 +433,13 @@ int Curl_cpool_check_limits(struct Curl_easy *data,
|
|||
" from %zu to reach destination limit of %zu",
|
||||
oldest_idle->connection_id,
|
||||
Curl_llist_count(&bundle->conns), dest_limit);
|
||||
Curl_conn_terminate(cpool->idata, oldest_idle, FALSE);
|
||||
cpool_evict_conn(cpool, data, oldest_idle);
|
||||
|
||||
/* in case the bundle was destroyed in disconnect, look it up again */
|
||||
bundle = cpool_find_bundle(cpool, conn);
|
||||
live = bundle ? Curl_llist_count(&bundle->conns) : 0;
|
||||
}
|
||||
shutdowns = Curl_cshutdn_dest_count(cpool->idata, conn->destination);
|
||||
shutdowns = Curl_cshutdn_dest_count(data, conn->destination);
|
||||
}
|
||||
if((live + shutdowns) >= dest_limit) {
|
||||
res = CPOOL_LIMIT_DEST;
|
||||
|
|
@ -431,7 +448,7 @@ int Curl_cpool_check_limits(struct Curl_easy *data,
|
|||
}
|
||||
|
||||
if(total_limit) {
|
||||
shutdowns = Curl_cshutdn_count(cpool->idata);
|
||||
shutdowns = Curl_cshutdn_count(data);
|
||||
while((cpool->num_conn + shutdowns) >= total_limit) {
|
||||
if(shutdowns) {
|
||||
/* close one connection in shutdown right away, if we can */
|
||||
|
|
@ -448,9 +465,9 @@ int Curl_cpool_check_limits(struct Curl_easy *data,
|
|||
FMT_OFF_T " from %zu to reach total "
|
||||
"limit of %zu",
|
||||
oldest_idle->connection_id, cpool->num_conn, total_limit);
|
||||
Curl_conn_terminate(cpool->idata, oldest_idle, FALSE);
|
||||
cpool_evict_conn(cpool, data, oldest_idle);
|
||||
}
|
||||
shutdowns = Curl_cshutdn_count(cpool->idata);
|
||||
shutdowns = Curl_cshutdn_count(data);
|
||||
}
|
||||
if((cpool->num_conn + shutdowns) >= total_limit) {
|
||||
res = CPOOL_LIMIT_TOTAL;
|
||||
|
|
@ -582,7 +599,7 @@ bool Curl_cpool_conn_now_idle(struct Curl_easy *data,
|
|||
oldest_idle = cpool_get_oldest_idle(cpool, Curl_pgrs_now(data));
|
||||
kept = (oldest_idle != conn);
|
||||
if(oldest_idle) {
|
||||
Curl_conn_terminate(data, oldest_idle, FALSE);
|
||||
cpool_evict_conn(cpool, data, oldest_idle);
|
||||
}
|
||||
}
|
||||
if(do_lock)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue