ratelimit blocking: fix busy loop

Fix the pollset in perform state to not add sockets for directions
that are blocked. This otherwise will lead to busy loops for a
transfer that cannot be progressed.

Reported-by: Fizn-Ahmd on github
Fixes #20091
Closes #20109
This commit is contained in:
Stefan Eissing 2025-12-29 11:21:31 +01:00 committed by Daniel Stenberg
parent 16d5f2a566
commit 52ac8104e1
No known key found for this signature in database
GPG key ID: 5CC908FDB71E12C2
3 changed files with 19 additions and 9 deletions

View file

@ -1080,10 +1080,9 @@ static CURLcode mstate_perform_pollset(struct Curl_easy *data,
result = conn->handler->perform_pollset(data, ps);
else {
/* Default is to obey the data->req.keepon flags for send/recv */
if(CURL_WANT_RECV(data) && CONN_SOCK_IDX_VALID(conn->recv_idx)) {
if(Curl_req_want_recv(data) && CONN_SOCK_IDX_VALID(conn->recv_idx)) {
result = Curl_pollset_add_in(data, ps, conn->sock[conn->recv_idx]);
}
if(!result && Curl_req_want_send(data) &&
CONN_SOCK_IDX_VALID(conn->send_idx)) {
result = Curl_pollset_add_out(data, ps, conn->sock[conn->send_idx]);

View file

@ -415,16 +415,25 @@ bool Curl_req_sendbuf_empty(struct Curl_easy *data)
bool Curl_req_want_send(struct Curl_easy *data)
{
/* Not done and
* - KEEP_SEND and not PAUSEd.
* - or request has buffered data to send
* - or transfer connection has pending data to send */
/* Not done and upload not blocked and either one of
* - KEEP_SEND
* - request has buffered data to send
* - connection has pending data to send */
return !data->req.done &&
!Curl_rlimit_is_blocked(&data->progress.ul.rlimit) &&
((data->req.keepon & KEEP_SEND) ||
!Curl_req_sendbuf_empty(data) ||
Curl_xfer_needs_flush(data));
}
bool Curl_req_want_recv(struct Curl_easy *data)
{
/* Not done and download not blocked and KEEP_RECV */
return !data->req.done &&
!Curl_rlimit_is_blocked(&data->progress.dl.rlimit) &&
(data->req.keepon & KEEP_RECV);
}
bool Curl_req_done_sending(struct Curl_easy *data)
{
return data->req.upload_done && !Curl_req_want_send(data);

View file

@ -193,11 +193,13 @@ bool Curl_req_done_sending(struct Curl_easy *data);
*/
CURLcode Curl_req_send_more(struct Curl_easy *data);
/**
* TRUE iff the request wants to send, e.g. has buffered bytes.
*/
/* TRUE if the request wants to send, e.g. is not done sending
* and is not blocked. */
bool Curl_req_want_send(struct Curl_easy *data);
/* TRUE if the request wants to receive and is not blocked. */
bool Curl_req_want_recv(struct Curl_easy *data);
/**
* TRUE iff the request has no buffered bytes yet to send.
*/