From 5f4aaf8b66ef04208c1c2121d4b780c792303f32 Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Tue, 30 Apr 2024 11:07:28 +0200
Subject: [PATCH] tool_cb_rea: limit rate unpause for -T . uploads
Reference:https://github.com/curl/curl/pull/13506

---
 src/tool_cb_rea.c | 30 ++++++++++++++++++++++++++++--
 1 file changed, 28 insertions(+), 2 deletions(-)

diff --git a/src/tool_cb_rea.c b/src/tool_cb_rea.c
index d70a9b9..f510f81 100644
--- a/src/tool_cb_rea.c
+++ b/src/tool_cb_rea.c
@@ -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;
-- 
2.27.0

