Git fork

progress: pay attention to (customized) delay time

Using one of the start_delayed_*() functions, clients of the progress
API can request that a progress meter is only shown after some time.
To do that, the implementation intends to count down the number of
seconds stored in struct progress by observing flag progress_update,
which the timer interrupt handler sets when a second has elapsed. This
works during the first second of the delay. But the code forgets to
reset the flag to zero, so that subsequent calls of display_progress()
think that another second has elapsed and decrease the count again
until zero is reached. Due to the frequency of the calls, this happens
without an observable delay in practice, so that the effective delay is
always just one second.

This bug has been with us since the inception of the feature. Despite
having been touched on various occasions, such as 8aade107dd84
(progress: simplify "delayed" progress API), 9c5951cacf5c (progress:
drop delay-threshold code), and 44a4693bfcec (progress: create
GIT_PROGRESS_DELAY), the short delay went unnoticed.

Copy the flag state into a local variable and reset the global flag
right away so that we can detect the next clock tick correctly.

Since we have not had any complaints that the delay of one second is
too short nor that GIT_PROGRESS_DELAY is ignored, people seem to be
comfortable with the status quo. Therefore, set the default to 1 to
keep the current behavior.

Signed-off-by: Johannes Sixt <j6t@kdbg.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>

authored by

Johannes Sixt and committed by
Junio C Hamano
457534d0 f368df43

+8 -6
+1 -1
Documentation/git.adoc
··· 684 684 685 685 `GIT_PROGRESS_DELAY`:: 686 686 A number controlling how many seconds to delay before showing 687 - optional progress indicators. Defaults to 2. 687 + optional progress indicators. Defaults to 1. 688 688 689 689 `GIT_EDITOR`:: 690 690 This environment variable overrides `$EDITOR` and `$VISUAL`.
+7 -5
progress.c
··· 114 114 const char *tp; 115 115 struct strbuf *counters_sb = &progress->counters_sb; 116 116 int show_update = 0; 117 + int update = !!progress_update; 117 118 int last_count_len = counters_sb->len; 118 119 119 - if (progress->delay && (!progress_update || --progress->delay)) 120 + progress_update = 0; 121 + 122 + if (progress->delay && (!update || --progress->delay)) 120 123 return; 121 124 122 125 progress->last_value = n; 123 126 tp = (progress->throughput) ? progress->throughput->display.buf : ""; 124 127 if (progress->total) { 125 128 unsigned percent = n * 100 / progress->total; 126 - if (percent != progress->last_percent || progress_update) { 129 + if (percent != progress->last_percent || update) { 127 130 progress->last_percent = percent; 128 131 129 132 strbuf_reset(counters_sb); ··· 133 136 tp); 134 137 show_update = 1; 135 138 } 136 - } else if (progress_update) { 139 + } else if (update) { 137 140 strbuf_reset(counters_sb); 138 141 strbuf_addf(counters_sb, "%"PRIuMAX"%s", (uintmax_t)n, tp); 139 142 show_update = 1; ··· 166 169 } 167 170 fflush(stderr); 168 171 } 169 - progress_update = 0; 170 172 } 171 173 } 172 174 ··· 281 283 static int delay_in_secs = -1; 282 284 283 285 if (delay_in_secs < 0) 284 - delay_in_secs = git_env_ulong("GIT_PROGRESS_DELAY", 2); 286 + delay_in_secs = git_env_ulong("GIT_PROGRESS_DELAY", 1); 285 287 286 288 return delay_in_secs; 287 289 }