Skip to content

Commit

Permalink
tool_cb_rea: limit rate unpause for -T . uploads
Browse files Browse the repository at this point in the history
To avoid getting stuck in a busy-loop when nothing is read from stdin,
this function now checks the call rate and might enforce a short sleep
when called repeatedly without uploading anything. It is a crude
work-around to avoid a 100% busy CPU.

Reported-by: magisterquis on hackerone
Fixes #13174
Closes #13506
  • Loading branch information
bagder committed May 2, 2024
1 parent 38593db commit 5f4aaf8
Showing 1 changed file with 28 additions and 2 deletions.
30 changes: 28 additions & 2 deletions src/tool_cb_rea.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#include "tool_operate.h"
#include "tool_util.h"
#include "tool_msgs.h"
#include "tool_sleep.h"

#include "memdebug.h" /* keep this as LAST include */

Expand Down Expand Up @@ -124,8 +125,33 @@ int tool_readbusy_cb(void *clientp,
(void)ulnow; /* unused */

if(config->readbusy) {
config->readbusy = FALSE;
curl_easy_pause(per->curl, CURLPAUSE_CONT);
/* lame code to keep the rate down because the input might not deliver
anything, get paused again and come back here immediately */
static long rate = 500;
static struct timeval prev;
static curl_off_t ulprev;

if(ulprev == ulnow) {
/* it did not upload anything since last call */
struct timeval now = tvnow();
if(prev.tv_sec)
/* get a rolling average rate */
/* rate = rate - rate/4 + tvdiff(now, prev)/4; */
rate -= rate/4 - tvdiff(now, prev)/4;
prev = now;
}
else {
rate = 50;
ulprev = ulnow;
}
if(rate >= 50) {
/* keeps the looping down to 20 times per second in the crazy case */
config->readbusy = FALSE;
curl_easy_pause(per->curl, CURLPAUSE_CONT);
}
else
/* sleep half a period */
tool_go_sleep(25);
}

return per->noprogress? 0 : CURL_PROGRESSFUNC_CONTINUE;
Expand Down

0 comments on commit 5f4aaf8

Please sign in to comment.