mirror of
https://github.com/curl/curl.git
synced 2025-02-05 14:30:10 +08:00
tool_cb_rea: limit rate unpause for -T . uploads
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
This commit is contained in:
parent
38593db4a0
commit
5f4aaf8b66
@ -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 */
|
||||
|
||||
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user