]> git.ipfire.org Git - thirdparty/git.git/blame - progress.c
prune-packed: don't call display_progress() for every file
[thirdparty/git.git] / progress.c
CommitLineData
96a02f8f
NP
1#include "git-compat-util.h"
2#include "progress.h"
3
4static volatile sig_atomic_t progress_update;
5
6static void progress_interval(int signum)
7{
8 progress_update = 1;
9}
10
11static void set_progress_signal(void)
12{
13 struct sigaction sa;
14 struct itimerval v;
15
180a9f22
NP
16 progress_update = 0;
17
96a02f8f
NP
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);
23
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);
28}
29
30static void clear_progress_signal(void)
31{
32 struct itimerval v = {{0,},};
33 setitimer(ITIMER_REAL, &v, NULL);
34 signal(SIGALRM, SIG_IGN);
35 progress_update = 0;
36}
37
42e18fbf 38static int display(struct progress *progress, unsigned n, int done)
96a02f8f 39{
42e18fbf
NP
40 char *eol;
41
180a9f22 42 if (progress->delay) {
180a9f22
NP
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;
53 }
54 }
180a9f22 55 }
42e18fbf
NP
56
57 progress->last_value = n;
58 eol = done ? ", done. \n" : " \r";
96a02f8f
NP
59 if (progress->total) {
60 unsigned percent = n * 100 / progress->total;
61 if (percent != progress->last_percent || progress_update) {
62 progress->last_percent = percent;
42e18fbf
NP
63 fprintf(stderr, "%s: %3u%% (%u/%u)%s", progress->title,
64 percent, n, progress->total, eol);
96a02f8f
NP
65 progress_update = 0;
66 return 1;
67 }
68 } else if (progress_update) {
42e18fbf 69 fprintf(stderr, "%s: %u%s", progress->title, n, eol);
96a02f8f
NP
70 progress_update = 0;
71 return 1;
72 }
42e18fbf 73
96a02f8f
NP
74 return 0;
75}
76
42e18fbf 77int display_progress(struct progress *progress, unsigned n)
96a02f8f 78{
42e18fbf 79 return display(progress, n, 0);
96a02f8f
NP
80}
81
180a9f22 82void start_progress_delay(struct progress *progress, const char *title,
42e18fbf 83 unsigned total, unsigned percent_treshold, unsigned delay)
180a9f22 84{
42e18fbf 85 progress->title = title;
180a9f22 86 progress->total = total;
42e18fbf 87 progress->last_value = -1;
180a9f22
NP
88 progress->last_percent = -1;
89 progress->delayed_percent_treshold = percent_treshold;
180a9f22
NP
90 progress->delay = delay;
91 set_progress_signal();
92}
93
42e18fbf
NP
94void start_progress(struct progress *progress, const char *title, unsigned total)
95{
96 start_progress_delay(progress, title, total, 0, 0);
97}
98
96a02f8f
NP
99void stop_progress(struct progress *progress)
100{
42e18fbf
NP
101 if (progress->last_value != -1) {
102 /* Force the last update */
103 progress_update = 1;
104 display(progress, progress->last_value, 1);
105 }
96a02f8f 106 clear_progress_signal();
96a02f8f 107}