Skip to content

Commit

Permalink
easy: fix curl_easy_upkeep for shared connection caches
Browse files Browse the repository at this point in the history
- Predict which connection cache is or will be used by the easy handle
  and perform connection upkeep on that cache.

This change allows curl_easy_upkeep to be effective on easy handles that
are using a shared connection cache, either from a user created shared
connection cache or a user created multi which has its own shared
connection cache.

Prior to this change curl_easy_upkeep would upkeep the connection cache
for the easy handle only if that cache was from the multi owned by the
easy handle (ie curl_easy_perform was previously called and there's a
connection cache exclusive to the easy handle in
data->multi_easy->conn_cache).

Ref: https://curl.se/mail/lib-2024-01/0016.html

Closes #xxxx
  • Loading branch information
jay committed Jan 10, 2024
1 parent 77c3c1a commit 2bb9346
Showing 1 changed file with 20 additions and 2 deletions.
22 changes: 20 additions & 2 deletions lib/easy.c
Expand Up @@ -1346,13 +1346,31 @@ static CURLcode upkeep(struct conncache *conn_cache, void *data)
*/
CURLcode curl_easy_upkeep(struct Curl_easy *data)
{
struct conncache *conn_cache;

/* Verify that we got an easy handle we can work with. */
if(!GOOD_EASY_HANDLE(data))
return CURLE_BAD_FUNCTION_ARGUMENT;

if(data->multi_easy) {
/* predict the connection cache that will next be used by the easy handle.
if the easy handle is currently in a multi then data->state.conn_cache
should point to the in-use cache. otherwise use the same logic that a
multi would use to assign it: if there's a user-specified shared cache
then use that, else use the multi's default shared cache. */
DEBUGASSERT(!data->multi || data->state.conn_cache);
conn_cache =
data->state.conn_cache ?
data->state.conn_cache :
(data->share && (data->share->specifier & (1<< CURL_LOCK_DATA_CONNECT))) ?
&data->share->conn_cache :
data->multi ?
&data->multi->conn_cache :
data->multi_easy ?
&data->multi_easy->conn_cache : NULL;

if(conn_cache) {
/* Use the common function to keep connections alive. */
return upkeep(&data->multi_easy->conn_cache, data);
return upkeep(conn_cache, data);
}
else {
/* No connections, so just return success */
Expand Down

0 comments on commit 2bb9346

Please sign in to comment.