transfer: do not use EXPIRE_NOW while blocked

- When a transfer sets `data->state.select_bits`, it is
  scheduled for rerun with EXPIRE_NOW. If such a transfer
  is blocked (due to PAUSE, for example), this will lead to
  a busy loop.
- multi.c: check for transfer block
- sendf.*: add Curl_xfer_is_blocked()
- sendf.*: add client reader `is_paused()` callback
- implement is_paused()` callback where needed

Closes #13908
This commit is contained in:
Stefan Eissing 2024-06-07 14:38:51 +02:00 committed by Daniel Stenberg
parent 1424d507aa
commit 3841569ec8
No known key found for this signature in database
GPG key ID: 5CC908FDB71E12C2
10 changed files with 86 additions and 2 deletions

View file

@ -1323,3 +1323,15 @@ CURLcode Curl_xfer_send_shutdown(struct Curl_easy *data, bool *done)
sockindex = (data->conn->writesockfd == data->conn->sock[SECONDARYSOCKET]);
return Curl_conn_shutdown(data, sockindex, done);
}
bool Curl_xfer_is_blocked(struct Curl_easy *data)
{
bool want_send = ((data)->req.keepon & KEEP_SEND);
bool want_recv = ((data)->req.keepon & KEEP_RECV);
if(!want_send)
return (want_recv && Curl_cwriter_is_paused(data));
else if(!want_recv)
return (want_send && Curl_creader_is_paused(data));
else
return Curl_creader_is_paused(data) && Curl_cwriter_is_paused(data);
}