On Wed, Jun 23, 2021 at 07:48:18PM +0200, Ævar Arnfjörð Bjarmason wrote: > Ever since the progress.c code was added in 96a02f8f6d2 (common > progress display support, 2007-04-18) we have been driven purely by > calls to the display() function (via the public display_progress()), > or via stop_progress(). Even though we got a signal and invoked > progress_interval() that function would not actually emit progress > output for us. > > Thus in cases like "git gc" we don't emit any "Enumerating Objects" > output until we get past the setup code, and start enumerating > objects, we'll now (at least on my laptop) show output earlier, and > emit a "stalled" message before we start the count. > > But more generally, this is a first step towards never showing a > hanging progress bar from the user's perspective. If we're truly > taking a very long time with one item we can show some spinner that we > update every time we get a signal. We don't right now, and only > special-case the most common case of hanging before we get to the > first item. > > Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@xxxxxxxxx> > --- > progress.c | 7 +++++ > t/t0500-progress-display.sh | 63 ++++++++++++++++++++++++++++++++++--- > 2 files changed, 66 insertions(+), 4 deletions(-) > > diff --git a/progress.c b/progress.c > index 6c4038df791..35847d3a7f2 100644 > --- a/progress.c > +++ b/progress.c > @@ -255,6 +255,13 @@ void display_progress(struct progress *progress, uint64_t n) > static void progress_interval(int signum) > { > progress_update = 1; > + > + if (global_progress->last_value != -1) > + return; > + > + display(global_progress, 0, _(", stalled."), 0); We have a few progress lines that are updated from multiple threads, and to prevent concurrency issues those threads call display() while holding a mutex. This call without synchronization causes undefined behavior.