From f5700ea88baa5baeb63b7cd42bd12fb03f4e0f4e Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 15 Mar 2018 16:43:00 +0100 Subject: rate-limit: use three second window to better handle high speeds MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Due to very frequent updates of the rate limit "window", it could attempt to rate limit within the same milliseconds and that then made the calculations wrong, leading to it not behaving correctly on very fast transfers. This new logic updates the rate limit "window" to be no shorter than the last three seconds and only updating the timestamps for this when switching between the states TOOFAST/PERFORM. Reported-by: 刘佩东 Fixes #2386 Closes #2388 --- lib/multi.c | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) (limited to 'lib/multi.c') diff --git a/lib/multi.c b/lib/multi.c index 98e5fca2a..69df90288 100644 --- a/lib/multi.c +++ b/lib/multi.c @@ -1823,22 +1823,26 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, if(!result) { send_timeout_ms = 0; if(data->set.max_send_speed > 0) - send_timeout_ms = Curl_pgrsLimitWaitTime(data->progress.uploaded, - data->progress.ul_limit_size, - data->set.max_send_speed, - data->progress.ul_limit_start, - now); + send_timeout_ms = + Curl_pgrsLimitWaitTime(data->progress.uploaded, + data->progress.ul_limit_size, + data->set.max_send_speed, + data->progress.ul_limit_start, + now); recv_timeout_ms = 0; if(data->set.max_recv_speed > 0) - recv_timeout_ms = Curl_pgrsLimitWaitTime(data->progress.downloaded, - data->progress.dl_limit_size, - data->set.max_recv_speed, - data->progress.dl_limit_start, - now); - - if(send_timeout_ms <= 0 && recv_timeout_ms <= 0) + recv_timeout_ms = + Curl_pgrsLimitWaitTime(data->progress.downloaded, + data->progress.dl_limit_size, + data->set.max_recv_speed, + data->progress.dl_limit_start, + now); + + if(!send_timeout_ms && !recv_timeout_ms) { multistate(data, CURLM_STATE_PERFORM); + Curl_ratelimit(data, now); + } else if(send_timeout_ms >= recv_timeout_ms) Curl_expire(data, send_timeout_ms, EXPIRE_TOOFAST); else @@ -1870,7 +1874,8 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, data->progress.dl_limit_start, now); - if(send_timeout_ms > 0 || recv_timeout_ms > 0) { + if(send_timeout_ms || recv_timeout_ms) { + Curl_ratelimit(data, now); multistate(data, CURLM_STATE_TOOFAST); if(send_timeout_ms >= recv_timeout_ms) Curl_expire(data, send_timeout_ms, EXPIRE_TOOFAST); -- cgit v1.2.3