Skip to content

Commit e56a707

Browse files
committed
Merge branch 'cb/daemon-reap-children' into seen
Futz with SIGCHLD handling in "git daemon". Comments? * cb/daemon-reap-children: daemon: explicitly allow EINTR during poll() daemon: use sigaction() to install child_handler() compat/posix.h: track SA_RESTART fallback
2 parents f01714b + bc91b4b commit e56a707

File tree

7 files changed

+85
-10
lines changed

7 files changed

+85
-10
lines changed

Makefile

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ include shared.mak
3737
# when attempting to read from an fopen'ed directory (or even to fopen
3838
# it at all).
3939
#
40+
# Define USE_NON_POSIX_SIGNAL if don't have support for SA_RESTART or
41+
# prefer to use ANSI C signal() over POSIX sigaction()
42+
#
4043
# Define OPEN_RETURNS_EINTR if your open() system call may return EINTR
4144
# when a signal is received (as opposed to restarting).
4245
#
@@ -1810,6 +1813,9 @@ ifdef FREAD_READS_DIRECTORIES
18101813
COMPAT_CFLAGS += -DFREAD_READS_DIRECTORIES
18111814
COMPAT_OBJS += compat/fopen.o
18121815
endif
1816+
ifdef USE_NON_POSIX_SIGNAL
1817+
COMPAT_CFLAGS += -DUSE_NON_POSIX_SIGNAL
1818+
endif
18131819
ifdef OPEN_RETURNS_EINTR
18141820
COMPAT_CFLAGS += -DOPEN_RETURNS_EINTR
18151821
endif

compat/mingw-posix.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,6 @@ struct sigaction {
9595
sig_handler_t sa_handler;
9696
unsigned sa_flags;
9797
};
98-
#define SA_RESTART 0
9998

10099
struct itimerval {
101100
struct timeval it_value, it_interval;

compat/posix.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,14 @@ char *gitdirname(char *);
250250
#define NAME_MAX 255
251251
#endif
252252

253+
/*
254+
* On most systems <signal.h> would have given us this, but
255+
* not on some systems (e.g. NonStop, QNX).
256+
*/
257+
#ifndef SA_RESTART
258+
# define SA_RESTART 0 /* disabled for sigaction() */
259+
#endif
260+
253261
typedef uintmax_t timestamp_t;
254262
#define PRItime PRIuMAX
255263
#define parse_timestamp strtoumax

config.mak.uname

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -480,6 +480,7 @@ ifeq ($(uname_S),Windows)
480480
NO_STRTOUMAX = YesPlease
481481
NO_MKDTEMP = YesPlease
482482
NO_INTTYPES_H = YesPlease
483+
USE_NON_POSIX_SIGNAL = YesPlease
483484
CSPRNG_METHOD = rtlgenrandom
484485
# VS2015 with UCRT claims that snprintf and friends are C99 compliant,
485486
# so we don't need this:
@@ -648,8 +649,6 @@ ifeq ($(uname_S),NONSTOP_KERNEL)
648649
FREAD_READS_DIRECTORIES = UnfortunatelyYes
649650

650651
# Not detected (nor checked for) by './configure'.
651-
# We don't have SA_RESTART on NonStop, unfortunalety.
652-
COMPAT_CFLAGS += -DSA_RESTART=0
653652
# Apparently needed in compat/fnmatch/fnmatch.c.
654653
COMPAT_CFLAGS += -DHAVE_STRING_H=1
655654
NO_ST_BLOCKS_IN_STRUCT_STAT = YesPlease
@@ -658,6 +657,7 @@ ifeq ($(uname_S),NONSTOP_KERNEL)
658657
NO_MMAP = YesPlease
659658
NO_POLL = YesPlease
660659
NO_INTPTR_T = UnfortunatelyYes
660+
USE_NON_POSIX_SIGNAL = UnfortunatelyYes
661661
CSPRNG_METHOD = openssl
662662
SANE_TOOL_PATH = /usr/coreutils/bin:/usr/local/bin
663663
SHELL_PATH = /usr/coreutils/bin/bash
@@ -693,6 +693,7 @@ ifeq ($(uname_S),MINGW)
693693
NEEDS_LIBICONV = YesPlease
694694
NO_STRTOUMAX = YesPlease
695695
NO_MKDTEMP = YesPlease
696+
USE_NON_POSIX_SIGNAL = YesPlease
696697
NO_SVN_TESTS = YesPlease
697698

698699
# The builtin FSMonitor requires Named Pipes and Threads on Windows.
@@ -776,7 +777,6 @@ ifeq ($(uname_S),MINGW)
776777
endif
777778
endif
778779
ifeq ($(uname_S),QNX)
779-
COMPAT_CFLAGS += -DSA_RESTART=0
780780
EXPAT_NEEDS_XMLPARSE_H = YesPlease
781781
HAVE_STRINGS_H = YesPlease
782782
NEEDS_SOCKET = YesPlease
@@ -788,4 +788,5 @@ ifeq ($(uname_S),QNX)
788788
NO_PTHREADS = YesPlease
789789
NO_STRCASESTR = YesPlease
790790
NO_STRLCPY = YesPlease
791+
USE_NON_POSIX_SIGNAL = UnfortunatelyYes
791792
endif

configure.ac

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -862,6 +862,23 @@ fi
862862
GIT_CONF_SUBST([ICONV_OMITS_BOM])
863863
fi
864864

865+
# Define USE_NON_POSIX_SIGNAL if don't have support for SA_RESTART or
866+
# prefer using ANSI C signal() over POSIX sigaction()
867+
868+
AC_CACHE_CHECK([whether SA_RESTART is supported], [ac_cv_siginterrupt], [
869+
AC_COMPILE_IFELSE(
870+
[AC_LANG_PROGRAM([#include <signal.h>], [[
871+
#ifdef SA_RESTART
872+
#endif
873+
siginterrupt(SIGCHLD, 1)
874+
]])],[ac_cv_siginterrupt=yes],[
875+
ac_cv_siginterrupt=no
876+
USE_NON_POSIX_SIGNAL=UnfortunatelyYes
877+
]
878+
)
879+
])
880+
GIT_CONF_SUBST([USE_NON_POSIX_SIGNAL])
881+
865882
## Checks for typedefs, structures, and compiler characteristics.
866883
AC_MSG_NOTICE([CHECKS for typedefs, structures, and compiler characteristics])
867884
#

daemon.c

Lines changed: 46 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -912,14 +912,19 @@ static void handle(int incoming, struct sockaddr *addr, socklen_t addrlen)
912912
add_child(&cld, addr, addrlen);
913913
}
914914

915-
static void child_handler(int signo UNUSED)
915+
static void child_handler(int signo MAYBE_UNUSED)
916916
{
917917
/*
918-
* Otherwise empty handler because systemcalls will get interrupted
919-
* upon signal receipt
920-
* SysV needs the handler to be rearmed
918+
* Otherwise empty handler because systemcalls should get interrupted
919+
* upon signal receipt.
921920
*/
922-
signal(SIGCHLD, child_handler);
921+
#ifdef USE_NON_POSIX_SIGNAL
922+
/*
923+
* SysV needs the handler to be rearmed, but this is known
924+
* to trigger infinite recursion crashes at least in AIX.
925+
*/
926+
signal(signo, child_handler);
927+
#endif
923928
}
924929

925930
static int set_reuse_addr(int sockfd)
@@ -1118,8 +1123,41 @@ static void socksetup(struct string_list *listen_addr, int listen_port, struct s
11181123
}
11191124
}
11201125

1126+
#ifndef USE_NON_POSIX_SIGNAL
1127+
1128+
static void set_signal_handler(struct sigaction *psa)
1129+
{
1130+
sigemptyset(&psa->sa_mask);
1131+
psa->sa_flags = SA_NOCLDSTOP | SA_RESTART;
1132+
psa->sa_handler = child_handler;
1133+
sigaction(SIGCHLD, psa, NULL);
1134+
}
1135+
1136+
static void set_sa_restart(struct sigaction *psa, int enable)
1137+
{
1138+
if (enable)
1139+
psa->sa_flags |= SA_RESTART;
1140+
else
1141+
psa->sa_flags &= ~SA_RESTART;
1142+
sigaction(SIGCHLD, psa, NULL);
1143+
}
1144+
1145+
#else
1146+
1147+
static void set_signal_handler(struct sigaction *psa UNUSED)
1148+
{
1149+
signal(SIGCHLD, child_handler);
1150+
}
1151+
1152+
static void set_sa_restart(struct sigaction *psa UNUSED, int enable UNUSED)
1153+
{
1154+
}
1155+
1156+
#endif
1157+
11211158
static int service_loop(struct socketlist *socklist)
11221159
{
1160+
struct sigaction sa;
11231161
struct pollfd *pfd;
11241162

11251163
CALLOC_ARRAY(pfd, socklist->nr);
@@ -1129,11 +1167,12 @@ static int service_loop(struct socketlist *socklist)
11291167
pfd[i].events = POLLIN;
11301168
}
11311169

1132-
signal(SIGCHLD, child_handler);
1170+
set_signal_handler(&sa);
11331171

11341172
for (;;) {
11351173
check_dead_children();
11361174

1175+
set_sa_restart(&sa, 0);
11371176
if (poll(pfd, socklist->nr, -1) < 0) {
11381177
if (errno != EINTR) {
11391178
logerror("Poll failed, resuming: %s",
@@ -1142,6 +1181,7 @@ static int service_loop(struct socketlist *socklist)
11421181
}
11431182
continue;
11441183
}
1184+
set_sa_restart(&sa, 1);
11451185

11461186
for (size_t i = 0; i < socklist->nr; i++) {
11471187
if (pfd[i].revents & POLLIN) {

meson.build

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1094,6 +1094,10 @@ else
10941094
build_options_config.set('NO_EXPAT', '1')
10951095
endif
10961096

1097+
if compiler.get_define('SA_RESTART', prefix: '#include <signal.h>') == ''
1098+
libgit_c_args += '-DUSE_NON_POSIX_SIGNAL'
1099+
endif
1100+
10971101
if not compiler.has_header('sys/select.h')
10981102
libgit_c_args += '-DNO_SYS_SELECT_H'
10991103
endif

0 commit comments

Comments
 (0)