]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
multi: make add_handle free any multi_easy
authorDaniel Stenberg <daniel@haxx.se>
Mon, 26 Feb 2024 08:50:49 +0000 (09:50 +0100)
committerDaniel Stenberg <daniel@haxx.se>
Tue, 27 Feb 2024 09:03:24 +0000 (10:03 +0100)
If the easy handle that is being added to a multi handle has previously
been used for curl_easy_perform(), there is a private multi handle here
that we can kill off. While it flushes some caches etc for the easy
handle would it be used for an easy interface transfer again after being
used in the multi stack, this cleanup simplifies behavior and uses less
memory.

Closes #12992

lib/easy.c
lib/multi.c

index 7ea1ce1f6361fc30354ab875403bc4772eb31a30..e6bda9bc8b163fe86a09e4efe9317bbba7294289 100644 (file)
@@ -742,7 +742,6 @@ static CURLcode easy_perform(struct Curl_easy *data, bool events)
     multi = Curl_multi_handle(1, 3, 7);
     if(!multi)
       return CURLE_OUT_OF_MEMORY;
-    data->multi_easy = multi;
   }
 
   if(multi->in_callback)
@@ -751,15 +750,18 @@ static CURLcode easy_perform(struct Curl_easy *data, bool events)
   /* Copy the MAXCONNECTS option to the multi handle */
   curl_multi_setopt(multi, CURLMOPT_MAXCONNECTS, (long)data->set.maxconnects);
 
+  data->multi_easy = NULL; /* pretend it does not exist */
   mcode = curl_multi_add_handle(multi, data);
   if(mcode) {
     curl_multi_cleanup(multi);
-    data->multi_easy = NULL;
     if(mcode == CURLM_OUT_OF_MEMORY)
       return CURLE_OUT_OF_MEMORY;
     return CURLE_FAILED_INIT;
   }
 
+  /* assign this after curl_multi_add_handle() */
+  data->multi_easy = multi;
+
   sigpipe_ignore(data, &pipe_st);
 
   /* run the transfer */
index c6869a3155cbba7284c0a883a20bf944d6a3a2d8..e0e871fe679c06139f566f9fff41674ef0d8d287 100644 (file)
@@ -530,6 +530,13 @@ CURLMcode curl_multi_add_handle(struct Curl_multi *multi,
     multi->dead = FALSE;
   }
 
+  if(data->multi_easy) {
+    /* if this easy handle was previously used for curl_easy_perform(), there
+       is a private multi handle here that we can kill */
+    curl_multi_cleanup(data->multi_easy);
+    data->multi_easy = NULL;
+  }
+
   /* Initialize timeout list for this handle */
   Curl_llist_init(&data->state.timeoutlist, NULL);