]> granicus.if.org Git - curl/commitdiff
multi: remove_handle: move pending connections
authorDaniel Stenberg <daniel@haxx.se>
Sun, 29 Mar 2015 21:48:32 +0000 (23:48 +0200)
committerDaniel Stenberg <daniel@haxx.se>
Sun, 29 Mar 2015 21:49:12 +0000 (23:49 +0200)
If the handle removed from the multi handle happens to be the one
"owning" the pipeline other transfers will be waiting indefinitely. Now
we move such handles back to connect to have them race (again) for
getting the connection and thus avoid hanging.

Bug: http://curl.haxx.se/bug/view.cgi?id=1465
Reported-by: Jiri Dvorak
lib/multi.c

index 4dc7f632a6e671a9ff287412f85f79f01d4d6880..c30835c3f5a77a43147ea669ebf92d65721b7099 100644 (file)
@@ -504,18 +504,22 @@ CURLMcode curl_multi_remove_handle(CURLM *multi_handle,
   if(!data->multi)
     return CURLM_OK; /* it is already removed so let's say it is fine! */
 
-
   premature = (data->mstate < CURLM_STATE_COMPLETED) ? TRUE : FALSE;
   easy_owns_conn = (data->easy_conn && (data->easy_conn->data == easy)) ?
     TRUE : FALSE;
 
   /* If the 'state' is not INIT or COMPLETED, we might need to do something
      nice to put the easy_handle in a good known state when this returns. */
-  if(premature)
+  if(premature) {
     /* this handle is "alive" so we need to count down the total number of
        alive connections when this is removed */
     multi->num_alive--;
 
+    /* When this handle gets removed, other handles may be able to get the
+       connection */
+    Curl_multi_process_pending_handles(multi);
+  }
+
   if(data->easy_conn &&
      data->mstate > CURLM_STATE_DO &&
      data->mstate < CURLM_STATE_COMPLETED) {