prune-packed: don't call display_progress() for every file
[git/debian.git] / progress.c
blob7629e0572bceb80086a5b2f503234340bc74361b
1 #include "git-compat-util.h"
2 #include "progress.h"
4 static volatile sig_atomic_t progress_update;
6 static void progress_interval(int signum)
8 progress_update = 1;
11 static void set_progress_signal(void)
13 struct sigaction sa;
14 struct itimerval v;
16 progress_update = 0;
18 memset(&sa, 0, sizeof(sa));
19 sa.sa_handler = progress_interval;
20 sigemptyset(&sa.sa_mask);
21 sa.sa_flags = SA_RESTART;
22 sigaction(SIGALRM, &sa, NULL);
24 v.it_interval.tv_sec = 1;
25 v.it_interval.tv_usec = 0;
26 v.it_value = v.it_interval;
27 setitimer(ITIMER_REAL, &v, NULL);
30 static void clear_progress_signal(void)
32 struct itimerval v = {{0,},};
33 setitimer(ITIMER_REAL, &v, NULL);
34 signal(SIGALRM, SIG_IGN);
35 progress_update = 0;
38 static int display(struct progress *progress, unsigned n, int done)
40 char *eol;
42 if (progress->delay) {
43 if (!progress_update || --progress->delay)
44 return 0;
45 if (progress->total) {
46 unsigned percent = n * 100 / progress->total;
47 if (percent > progress->delayed_percent_treshold) {
48 /* inhibit this progress report entirely */
49 clear_progress_signal();
50 progress->delay = -1;
51 progress->total = 0;
52 return 0;
57 progress->last_value = n;
58 eol = done ? ", done. \n" : " \r";
59 if (progress->total) {
60 unsigned percent = n * 100 / progress->total;
61 if (percent != progress->last_percent || progress_update) {
62 progress->last_percent = percent;
63 fprintf(stderr, "%s: %3u%% (%u/%u)%s", progress->title,
64 percent, n, progress->total, eol);
65 progress_update = 0;
66 return 1;
68 } else if (progress_update) {
69 fprintf(stderr, "%s: %u%s", progress->title, n, eol);
70 progress_update = 0;
71 return 1;
74 return 0;
77 int display_progress(struct progress *progress, unsigned n)
79 return display(progress, n, 0);
82 void start_progress_delay(struct progress *progress, const char *title,
83 unsigned total, unsigned percent_treshold, unsigned delay)
85 progress->title = title;
86 progress->total = total;
87 progress->last_value = -1;
88 progress->last_percent = -1;
89 progress->delayed_percent_treshold = percent_treshold;
90 progress->delay = delay;
91 set_progress_signal();
94 void start_progress(struct progress *progress, const char *title, unsigned total)
96 start_progress_delay(progress, title, total, 0, 0);
99 void stop_progress(struct progress *progress)
101 if (progress->last_value != -1) {
102 /* Force the last update */
103 progress_update = 1;
104 display(progress, progress->last_value, 1);
106 clear_progress_signal();