diff --git a/Makefile b/Makefile index e11340c1ae77ba..059382624c0e3a 100644 --- a/Makefile +++ b/Makefile @@ -142,11 +142,6 @@ include shared.mak # Define NO_PREAD if you have a problem with pread() system call (e.g. # cygwin1.dll before v1.5.22). # -# Define NO_SETITIMER if you don't have setitimer() -# -# Define NO_STRUCT_ITIMERVAL if you don't have struct itimerval -# This also implies NO_SETITIMER -# # Define NO_FAST_WORKING_DIRECTORY if accessing objects in pack files is # generally faster on your platform than accessing the working directory. # @@ -1888,13 +1883,6 @@ endif ifdef OBJECT_CREATION_USES_RENAMES COMPAT_CFLAGS += -DOBJECT_CREATION_MODE=1 endif -ifdef NO_STRUCT_ITIMERVAL - COMPAT_CFLAGS += -DNO_STRUCT_ITIMERVAL - NO_SETITIMER = YesPlease -endif -ifdef NO_SETITIMER - COMPAT_CFLAGS += -DNO_SETITIMER -endif ifdef NO_PREAD COMPAT_CFLAGS += -DNO_PREAD COMPAT_OBJS += compat/pread.o diff --git a/compat/mingw-posix.h b/compat/mingw-posix.h index 631a20868489be..7626fbe9017256 100644 --- a/compat/mingw-posix.h +++ b/compat/mingw-posix.h @@ -98,11 +98,6 @@ struct sigaction { #define SA_RESTART 0 #define SA_NOCLDSTOP 1 -struct itimerval { - struct timeval it_value, it_interval; -}; -#define ITIMER_REAL 0 - struct utsname { char sysname[16]; char nodename[1]; @@ -131,8 +126,6 @@ static inline int fchmod(int fildes UNUSED, mode_t mode UNUSED) static inline pid_t fork(void) { errno = ENOSYS; return -1; } #endif -static inline unsigned int alarm(unsigned int seconds UNUSED) -{ return 0; } static inline int fsync(int fd) { return _commit(fd); } static inline void sync(void) @@ -183,6 +176,7 @@ char *mingw_locate_in_PATH(const char *cmd); * implementations of missing functions */ +unsigned alarm(unsigned seconds); int pipe(int filedes[2]); unsigned int sleep (unsigned int seconds); int mkstemp(char *template); @@ -193,7 +187,6 @@ struct tm *localtime_r(const time_t *timep, struct tm *result); #endif int getpagesize(void); /* defined in MinGW's libgcc.a */ struct passwd *getpwuid(uid_t uid); -int setitimer(int type, struct itimerval *in, struct itimerval *out); int sigaction(int sig, struct sigaction *in, struct sigaction *out); int link(const char *oldpath, const char *newpath); int uname(struct utsname *buf); diff --git a/compat/mingw.c b/compat/mingw.c index 8538e3d1729d25..199f68ca6d9a81 100644 --- a/compat/mingw.c +++ b/compat/mingw.c @@ -2432,15 +2432,17 @@ static sig_handler_t timer_fn = SIG_DFL, sigint_fn = SIG_DFL; * the thread to terminate by setting the timer_event to the signalled * state. * But ticktack() interrupts the wait state after the timer's interval - * length to call the signal handler. + * length to call the signal handler if it still set. */ static unsigned __stdcall ticktack(void *dummy UNUSED) { + sig_handler_t fn = timer_fn; + while (WaitForSingleObject(timer_event, timer_interval) == WAIT_TIMEOUT) { - mingw_raise(SIGALRM); - if (one_shot) + if (one_shot || timer_fn != fn) break; + mingw_raise(SIGALRM); } return 0; } @@ -2478,37 +2480,23 @@ static void stop_timer_thread(void) timer_thread = NULL; } -static inline int is_timeval_eq(const struct timeval *i1, const struct timeval *i2) +unsigned alarm(unsigned seconds) { - return i1->tv_sec == i2->tv_sec && i1->tv_usec == i2->tv_usec; -} - -int setitimer(int type UNUSED, struct itimerval *in, struct itimerval *out) -{ - static const struct timeval zero; - static int atexit_done; - - if (out) - return errno = EINVAL, - error("setitimer param 3 != NULL not implemented"); - if (!is_timeval_eq(&in->it_interval, &zero) && - !is_timeval_eq(&in->it_interval, &in->it_value)) - return errno = EINVAL, - error("setitimer: it_interval must be zero or eq it_value"); - - if (timer_thread) - stop_timer_thread(); + static bool atexit_done; - if (is_timeval_eq(&in->it_value, &zero) && - is_timeval_eq(&in->it_interval, &zero)) - return 0; - - timer_interval = in->it_value.tv_sec * 1000 + in->it_value.tv_usec / 1000; - one_shot = is_timeval_eq(&in->it_interval, &zero); if (!atexit_done) { atexit(stop_timer_thread); - atexit_done = 1; + atexit_done = true; } + + timer_interval = seconds * 1000; + one_shot = !seconds; + if (timer_thread) { + if (!seconds) + stop_timer_thread(); + return 0; + } + return start_timer_thread(); } diff --git a/compat/posix.h b/compat/posix.h index 067a00f33b83f3..83af92d820f288 100644 --- a/compat/posix.h +++ b/compat/posix.h @@ -198,23 +198,6 @@ static inline time_t git_time(time_t *tloc) } #define time git_time -#ifdef NO_STRUCT_ITIMERVAL -struct itimerval { - struct timeval it_interval; - struct timeval it_value; -}; -#endif - -#ifdef NO_SETITIMER -static inline int git_setitimer(int which UNUSED, - const struct itimerval *value UNUSED, - struct itimerval *newvalue UNUSED) { - return 0; /* pretend success */ -} -#undef setitimer -#define setitimer(which,value,ovalue) git_setitimer(which,value,ovalue) -#endif - #ifndef NO_LIBGEN_H #include #else diff --git a/configure.ac b/configure.ac index cfb50112bf81ff..6b04aa37a82c73 100644 --- a/configure.ac +++ b/configure.ac @@ -872,13 +872,6 @@ case $ac_cv_type_socklen_t in esac GIT_CONF_SUBST([SOCKLEN_T]) -# -# Define NO_STRUCT_ITIMERVAL if you don't have struct itimerval. -AC_CHECK_TYPES([struct itimerval], -[NO_STRUCT_ITIMERVAL=], -[NO_STRUCT_ITIMERVAL=UnfortunatelyYes], -[#include ]) -GIT_CONF_SUBST([NO_STRUCT_ITIMERVAL]) # # Define USE_ST_TIMESPEC=YesPlease when stat.st_mtimespec.tv_nsec exists. # Define NO_NSEC=YesPlease when neither stat.st_mtim.tv_nsec nor @@ -1097,12 +1090,6 @@ GIT_CHECK_FUNC(sync_file_range, [HAVE_SYNC_FILE_RANGE=]) GIT_CONF_SUBST([HAVE_SYNC_FILE_RANGE]) -# -# Define NO_SETITIMER if you don't have setitimer. -GIT_CHECK_FUNC(setitimer, -[NO_SETITIMER=], -[NO_SETITIMER=YesPlease]) -GIT_CONF_SUBST([NO_SETITIMER]) # # Define NO_STRCASESTR if you don't have strcasestr. GIT_CHECK_FUNC(strcasestr, diff --git a/meson.build b/meson.build index 5dd299b4962d84..f33f20312511d5 100644 --- a/meson.build +++ b/meson.build @@ -1348,22 +1348,6 @@ else error('Native regex support requested but not found') endif -# setitimer and friends are provided by compat/mingw.c. -if host_machine.system() != 'windows' - if not compiler.compiles(''' - #include - void func(void) - { - struct itimerval value; - } - ''', name: 'struct itimerval') - libgit_c_args += '-DNO_STRUCT_ITIMERVAL' - libgit_c_args += '-DNO_SETITIMER' - elif not compiler.has_function('setitimer') - libgit_c_args += '-DNO_SETITIMER' - endif -endif - if compiler.has_member('struct stat', 'st_mtimespec.tv_nsec', prefix: '#include ') libgit_c_args += '-DUSE_ST_TIMESPEC' elif not compiler.has_member('struct stat', 'st_mtim.tv_nsec', prefix: '#include ') diff --git a/progress.c b/progress.c index 8d5ae70f3a9ec7..49e58e094a3f82 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,13 +71,15 @@ void progress_test_force_update(void) static void progress_interval(int signum UNUSED) { - progress_update = 1; + if (progress_update != 2) { + alarm(1); + progress_update = 1; + } } static void set_progress_signal(void) { struct sigaction sa; - struct itimerval v; if (progress_testing) return; @@ -85,20 +92,16 @@ static void set_progress_signal(void) sa.sa_flags = SA_RESTART; sigaction(SIGALRM, &sa, NULL); - v.it_interval.tv_sec = 1; - v.it_interval.tv_usec = 0; - v.it_value = v.it_interval; - setitimer(ITIMER_REAL, &v, NULL); + alarm(1); } static void clear_progress_signal(void) { - struct itimerval v = {{0,},}; - if (progress_testing) return; - setitimer(ITIMER_REAL, &v, NULL); + progress_update = 2; + alarm(0); signal(SIGALRM, SIG_IGN); progress_update = 0; } @@ -116,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); @@ -133,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; @@ -244,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); }