154 lines
5.3 KiB
Diff
154 lines
5.3 KiB
Diff
|
|
From 33bc3aae517e4884f08928be9d6e4c941ec3f489 Mon Sep 17 00:00:00 2001
|
||
|
|
From: vyachemail <vyachemail@gmail.com>
|
||
|
|
Date: Sat, 25 Jan 2020 00:30:09 +0600
|
||
|
|
Subject: [PATCH] Fix and cleanup progress bar code
|
||
|
|
|
||
|
|
*src/progress.c
|
||
|
|
(struct dot_progress) accumulated, rows: Type changed to wgint
|
||
|
|
(print_row_stats): Fix missing unit name 'T'
|
||
|
|
(dot_update): Add ability to reduce dot_draw runtime
|
||
|
|
(bar_update): Avoid integer overflow
|
||
|
|
---
|
||
|
|
src/progress.c | 63 ++++++++++++++++++++++++++++++++++++++++++--------
|
||
|
|
1 file changed, 54 insertions(+), 9 deletions(-)
|
||
|
|
|
||
|
|
diff --git a/src/progress.c b/src/progress.c
|
||
|
|
index 2fed72c0..296d8f30 100644
|
||
|
|
--- a/src/progress.c
|
||
|
|
+++ b/src/progress.c
|
||
|
|
@@ -220,11 +220,11 @@ struct dot_progress {
|
||
|
|
wgint total_length; /* expected total byte count when the
|
||
|
|
download finishes */
|
||
|
|
|
||
|
|
- int accumulated; /* number of bytes accumulated after
|
||
|
|
+ wgint accumulated; /* number of bytes accumulated after
|
||
|
|
the last printed dot */
|
||
|
|
|
||
|
|
double dltime; /* download time so far */
|
||
|
|
- int rows; /* number of rows printed so far */
|
||
|
|
+ wgint rows; /* number of rows printed so far */
|
||
|
|
int dots; /* number of dots printed in this row */
|
||
|
|
|
||
|
|
double last_timer_value;
|
||
|
|
@@ -282,6 +282,21 @@ dot_create (const char *f_download _GL_UNUSED, wgint initial, wgint total)
|
||
|
|
|
||
|
|
static const char *eta_to_human_short (int, bool);
|
||
|
|
|
||
|
|
+/* ADD_DOT_ROWS_THRS - minimal (1 << ADD_DOT_ROWS_THRS) ROWS to be added
|
||
|
|
+ to the current row if dp->accumulated too much.
|
||
|
|
+ Allows to reduce dot_draw io, times.
|
||
|
|
+ According to the way progress_update is currently has being called, this
|
||
|
|
+ should happens only when fuzzing, or (paranoia) if somehow buffer will
|
||
|
|
+ be too large.
|
||
|
|
+ Can be disabled by default if this is not fuzzing build. */
|
||
|
|
+#ifndef ADD_DOT_ROWS_THRS
|
||
|
|
+#if FUZZING
|
||
|
|
+#define ADD_DOT_ROWS_THRS 2
|
||
|
|
+#else
|
||
|
|
+#define ADD_DOT_ROWS_THRS 2
|
||
|
|
+#endif
|
||
|
|
+#endif /* ADD_DOT_ROWS_THRS */
|
||
|
|
+
|
||
|
|
/* Prints the stats (percentage of completion, speed, ETA) for current
|
||
|
|
row. DLTIME is the time spent downloading the data in current
|
||
|
|
row.
|
||
|
|
@@ -291,7 +306,11 @@ static const char *eta_to_human_short (int, bool);
|
||
|
|
might be worthwhile to split it to two different functions. */
|
||
|
|
|
||
|
|
static void
|
||
|
|
+#if ADD_DOT_ROWS_THRS
|
||
|
|
+print_row_stats (struct dot_progress *dp, double dltime, bool last, wgint added_rows)
|
||
|
|
+#else
|
||
|
|
print_row_stats (struct dot_progress *dp, double dltime, bool last)
|
||
|
|
+#endif
|
||
|
|
{
|
||
|
|
const wgint ROW_BYTES = opt.dot_bytes * opt.dots_in_line;
|
||
|
|
|
||
|
|
@@ -316,12 +335,16 @@ print_row_stats (struct dot_progress *dp, double dltime, bool last)
|
||
|
|
}
|
||
|
|
|
||
|
|
{
|
||
|
|
- static char names[] = {' ', 'K', 'M', 'G'};
|
||
|
|
+ static char names[] = {' ', 'K', 'M', 'G', 'T'};
|
||
|
|
int units;
|
||
|
|
double rate;
|
||
|
|
wgint bytes_this_row;
|
||
|
|
if (!last)
|
||
|
|
+#if ADD_DOT_ROWS_THRS
|
||
|
|
+ bytes_this_row = ROW_BYTES * added_rows;
|
||
|
|
+#else
|
||
|
|
bytes_this_row = ROW_BYTES;
|
||
|
|
+#endif
|
||
|
|
else
|
||
|
|
/* For last row also include bytes accumulated after last dot. */
|
||
|
|
bytes_this_row = dp->dots * opt.dot_bytes + dp->accumulated;
|
||
|
|
@@ -391,8 +414,9 @@ dot_draw (void *progress)
|
||
|
|
|
||
|
|
log_set_flush (false);
|
||
|
|
|
||
|
|
- for (; dp->accumulated >= dot_bytes; dp->accumulated -= dot_bytes)
|
||
|
|
+ while (dp->accumulated >= dot_bytes)
|
||
|
|
{
|
||
|
|
+ dp->accumulated -= dot_bytes;
|
||
|
|
if (dp->dots == 0)
|
||
|
|
logprintf (LOG_PROGRESS, "\n%6sK",
|
||
|
|
number_to_static_string (dp->rows * ROW_BYTES / 1024));
|
||
|
|
@@ -404,11 +428,26 @@ dot_draw (void *progress)
|
||
|
|
++dp->dots;
|
||
|
|
if (dp->dots >= opt.dots_in_line)
|
||
|
|
{
|
||
|
|
- if (dp->rows < INT_MAX)
|
||
|
|
- ++dp->rows;
|
||
|
|
dp->dots = 0;
|
||
|
|
-
|
||
|
|
+#if ADD_DOT_ROWS_THRS
|
||
|
|
+ {
|
||
|
|
+ wgint added_rows = 1;
|
||
|
|
+ if (dp->accumulated >= (ROW_BYTES << ADD_DOT_ROWS_THRS))
|
||
|
|
+ {
|
||
|
|
+ added_rows += dp->accumulated / ROW_BYTES;
|
||
|
|
+ dp->accumulated %= ROW_BYTES;
|
||
|
|
+ }
|
||
|
|
+ if (WGINT_MAX - dp->rows >= added_rows)
|
||
|
|
+ dp->rows += added_rows;
|
||
|
|
+ else
|
||
|
|
+ dp->rows = WGINT_MAX;
|
||
|
|
+ print_row_stats (dp, dp->dltime, false, added_rows);
|
||
|
|
+ }
|
||
|
|
+#else
|
||
|
|
+ if (dp->rows < WGINT_MAX)
|
||
|
|
+ ++dp->rows;
|
||
|
|
print_row_stats (dp, dp->dltime, false);
|
||
|
|
+#endif /* ADD_DOT_ROWS_THRS */
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
@@ -441,8 +480,11 @@ dot_finish (void *progress, double dltime)
|
||
|
|
dltime = INT_MAX - 1;
|
||
|
|
else if (dltime < 0)
|
||
|
|
dltime = 0;
|
||
|
|
-
|
||
|
|
+#if ADD_DOT_ROWS_THRS
|
||
|
|
+ print_row_stats (dp, dltime, true, 1);
|
||
|
|
+#else
|
||
|
|
print_row_stats (dp, dltime, true);
|
||
|
|
+#endif
|
||
|
|
logputs (LOG_VERBOSE, "\n\n");
|
||
|
|
log_set_flush (false);
|
||
|
|
|
||
|
|
@@ -721,7 +763,10 @@ bar_update (void *progress, wgint howmuch, double dltime)
|
||
|
|
struct bar_progress *bp = progress;
|
||
|
|
|
||
|
|
bp->dltime = dltime;
|
||
|
|
- bp->count += howmuch;
|
||
|
|
+ if (WGINT_MAX - (bp->count + bp->initial_length) >= howmuch)
|
||
|
|
+ bp->count += howmuch;
|
||
|
|
+ else
|
||
|
|
+ bp->count = WGINT_MAX - bp->initial_length;
|
||
|
|
if (bp->total_length > 0
|
||
|
|
&& bp->count + bp->initial_length > bp->total_length)
|
||
|
|
/* We could be downloading more than total_length, e.g. when the
|
||
|
|
--
|
||
|
|
2.19.1.windows.1
|
||
|
|
|