]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
easy: fix curl_easy_upkeep for shared connection caches
authorJay Satiro <raysatiro@yahoo.com>
Wed, 10 Jan 2024 08:53:23 +0000 (03:53 -0500)
committerJay Satiro <raysatiro@yahoo.com>
Sun, 4 Aug 2024 22:41:18 +0000 (18:41 -0400)
- Determine 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 https://github.com/curl/curl/pull/12677

docs/libcurl/curl_easy_upkeep.md
lib/easy.c

index c2d798d2dedd5d314e1978ab985dc287fdce4dee..1b2fef01a572b160aaef67e2ede535f7d467bf3a 100644 (file)
@@ -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
index 296dae8c135230e3ca78c906f7bf41a54f3a4d83..a0704b0ed3c88d419146b1f9375ddc4b198d91f6 100644 (file)
@@ -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 */