diff --git a/docs/libcurl/curl_easy_upkeep.md b/docs/libcurl/curl_easy_upkeep.md index c2d798d2de..1b2fef01a5 100644 --- a/docs/libcurl/curl_easy_upkeep.md +++ b/docs/libcurl/curl_easy_upkeep.md @@ -39,6 +39,10 @@ This function must be explicitly called in order to perform the upkeep work. The connection upkeep interval is set with CURLOPT_UPKEEP_INTERVAL_MS(3). +If you call this function on an easy handle that uses a shared connection cache +then upkeep is performed on the connections in that cache, even if those +connections were never used by the easy handle. (Added in 8.10.0) + # %PROTOCOLS% # EXAMPLE diff --git a/lib/easy.c b/lib/easy.c index 296dae8c13..a0704b0ed3 100644 --- a/lib/easy.c +++ b/lib/easy.c @@ -1335,13 +1335,30 @@ 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) { + if(Curl_is_in_callback(data)) + return CURLE_RECURSIVE_API_CALL; + + /* determine 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. */ + 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_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 */