git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH 2/2] progress: add a shutting down state to the SIGALRM handler

From
Carlo Marcelo Arenas Belón via GitGitGadget <gitgitgadget@gmail.com>
Date
Aug 23, 2025, 13:22 UTC
Message-ID
<0db98c3478e5e2f1aadcf6d773cf6519af482630.1755955378.git.gitgitgadget@gmail.com>
In-Reply-To
<pull.1960.git.1755955377.gitgitgadget@gmail.com>
From: =?UTF-8?q?Carlo=20Marcelo=20Arenas=20Bel=C3=B3n?= <carenas@gmail.com>

In a previous commit, sigitimer() was replaced by alarm(), but to keep the timer active, an extra call to `alarm(1)` was added to the signal handler, opening a potential race condition whem the timer is being cleared.

To avoid that, add an extra state to set during shutdown and adjust the logic to flag the potential need to update progress into the first bit instead.

Signed-off-by: Carlo Marcelo Arenas Belón <carenas@gmail.com>
---
 progress.c | 20 ++++++++++++++------
 1 file changed, 14 insertions(+), 6 deletions(-)
diff --git a/progress.c b/progress.c
index 71b305d1625d..49e58e094a3f 100644
--- a/progress.c
+++ b/progress.c
@@ -50,6 +50,11 @@ struct progress {
 	int split;
 };
 
+/*
+ * 0: no progress to report
+ * 1: potential update for progress to report
+ * 2: no more progress to report
+ */
 static volatile sig_atomic_t progress_update;
 
 /*
@@ -66,8 +71,10 @@ void progress_test_force_update(void)
 
 static void progress_interval(int signum UNUSED)
 {
-	progress_update = 1;
-	alarm(1);
+	if (progress_update != 2) {
+		alarm(1);
+		progress_update = 1;
+	}
 }
 
 static void set_progress_signal(void)
@@ -93,6 +100,7 @@ static void clear_progress_signal(void)
 	if (progress_testing)
 		return;
 
+	progress_update = 2;
 	alarm(0);
 	signal(SIGALRM, SIG_IGN);
 	progress_update = 0;
@@ -111,14 +119,14 @@ static void display(struct progress *progress, uint64_t n, const char *done)
 	int show_update = 0;
 	int last_count_len = counters_sb->len;
 
-	if (progress->delay && (!progress_update || --progress->delay))
+	if (progress->delay && (!(progress_update & 1) || --progress->delay))
 		return;
 
 	progress->last_value = n;
 	tp = (progress->throughput) ? progress->throughput->display.buf : "";
 	if (progress->total) {
 		unsigned percent = n * 100 / progress->total;
-		if (percent != progress->last_percent || progress_update) {
+		if (percent != progress->last_percent || (progress_update & 1)) {
 			progress->last_percent = percent;
 
 			strbuf_reset(counters_sb);
@@ -128,7 +136,7 @@ static void display(struct progress *progress, uint64_t n, const char *done)
 				    tp);
 			show_update = 1;
 		}
-	} else if (progress_update) {
+	} else if (progress_update & 1) {
 		strbuf_reset(counters_sb);
 		strbuf_addf(counters_sb, "%"PRIuMAX"%s", (uintmax_t)n, tp);
 		show_update = 1;
@@ -239,7 +247,7 @@ void display_throughput(struct progress *progress, uint64_t total)
 	tp->idx = (tp->idx + 1) % TP_IDX_MAX;
 
 	throughput_string(&tp->display, total, rate);
-	if (progress->last_value != -1 && progress_update)
+	if (progress->last_value != -1 && (progress_update & 1))
 		display(progress, progress->last_value, NULL);
 }
 
-- 
gitgitgadget
Previous: Carlo Marcelo Arenas Belón via GitGitGadgetNext: Johannes Sixt
Message 3 of 16 in “progress: replace setitimer() with alarm()”
  1. 0/2 progress: replace setitimer() with alarm()Carlo Marcelo Arenas Belón via GitGitGadget, Aug 23, 2025
  2. 1/2 progress: replace setitimer() with alarm()Carlo Marcelo Arenas Belón via GitGitGadget, Aug 23, 2025
  3. 2/2 progress: add a shutting down state to the SIGALRM handlerCarlo Marcelo Arenas Belón via GitGitGadget, Aug 23, 2025
  4. Johannes SixtAug 23, 2025
  5. Carlo Marcelo Arenas BelónAug 23, 2025
  6. Johannes SixtAug 23, 2025
  7. Junio C HamanoAug 23, 2025
  8. Junio C HamanoAug 23, 2025
  9. Johannes SixtAug 23, 2025
  10. progress: pay attention to (customized) delay timeJohannes Sixt, Aug 24, 2025
  11. Junio C HamanoAug 25, 2025
  12. Carlo Marcelo Arenas BelónAug 25, 2025
  13. Junio C HamanoAug 25, 2025
  14. progress: pay attention to (customized) delay timeJohannes Sixt, Aug 25, 2025
  15. Junio C HamanoAug 25, 2025
  16. Junio C HamanoAug 24, 2025

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.