Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Possible busy-looping in curl_multi_poll #4594

Closed
3dyd opened this issue Nov 14, 2019 · 3 comments
Closed

Possible busy-looping in curl_multi_poll #4594

3dyd opened this issue Nov 14, 2019 · 3 comments
Assignees

Comments

@3dyd
Copy link
Contributor

3dyd commented Nov 14, 2019

Take a look at this piece of code at the end of Curl_multi_wait:

curl/lib/multi.c

Lines 1150 to 1161 in 7a46aeb

if(!extrawait || extra_fds || curlfds)
/* if any socket was checked */
;
else {
long sleep_ms = 0;
/* Avoid busy-looping when there's nothing particular to wait for */
if(!curl_multi_timeout(multi, &sleep_ms) && sleep_ms) {
if(sleep_ms > timeout_ms)
sleep_ms = timeout_ms;
Curl_wait_ms((int)sleep_ms);
}

If curl_multi_poll is given valid empty multi handle (no easy handles were added to it [yet]) without extra curl_waitfd structures then sleep_ms receives value -1 from curl_multi_timeout effectively avoiding waiting for given timeout_ms period. So function returns immediately.

Is this intended behavior, and such edge case still has to be accounted by the caller to avoid busy-looping?

@bagder bagder self-assigned this Nov 14, 2019
@bagder
Copy link
Member

bagder commented Nov 14, 2019

I think it should wait for the timeout period in this case. Something like this?

diff --git a/lib/multi.c b/lib/multi.c
index 7e8e38dc9..db08ac636 100755
--- a/lib/multi.c
+++ b/lib/multi.c
@@ -1155,10 +1155,12 @@ static CURLMcode Curl_multi_wait(struct Curl_multi *multi,
 
     /* Avoid busy-looping when there's nothing particular to wait for */
     if(!curl_multi_timeout(multi, &sleep_ms) && sleep_ms) {
       if(sleep_ms > timeout_ms)
         sleep_ms = timeout_ms;
+      else if((sleep_ms < 0) && extrawait)
+        sleep_ms = timeout_ms;
       Curl_wait_ms((int)sleep_ms);
     }
   }
 
   return CURLM_OK;

@3dyd
Copy link
Contributor Author

3dyd commented Nov 14, 2019

Not sure if notification is fired if one comments diff directly, so I am duplicating it here:

else if((sleep_ms < 0) && extrawait)

extrawait is always true in this block.

@3dyd
Copy link
Contributor Author

3dyd commented Nov 14, 2019

Confirmed the change has fixed described issue.

@bagder bagder closed this as completed in 4e1eee1 Nov 14, 2019
@lock lock bot locked as resolved and limited conversation to collaborators Feb 12, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Development

Successfully merging a pull request may close this issue.

2 participants