From: Stefan Eissing Date: Mon, 29 Dec 2025 10:21:31 +0000 (+0100) Subject: ratelimit blocking: fix busy loop X-Git-Tag: curl-8_18_0~75 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=52ac8104e1396998110e0760ac780f4f2414831f;p=thirdparty%2Fcurl.git 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 --- diff --git a/lib/multi.c b/lib/multi.c index 92f6ca764d..aec0739c39 100644 --- a/lib/multi.c +++ b/lib/multi.c @@ -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]); diff --git a/lib/request.c b/lib/request.c index 90c10af99c..ad7f628f1a 100644 --- a/lib/request.c +++ b/lib/request.c @@ -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); diff --git a/lib/request.h b/lib/request.h index 0b006dc77c..389ae4d8b1 100644 --- a/lib/request.h +++ b/lib/request.h @@ -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. */