From: Phillip Wood <phillip.wood123@gmail.com>
To: "Carlo Marcelo Arenas Belón via GitGitGadget"
<gitgitgadget@gmail.com>,
git@vger.kernel.org
Cc: "Carlo Marcelo Arenas Belón" <carenas@gmail.com>,
"Chris Torek" <chris.torek@gmail.com>,
"Phillip Wood" <phillip.wood123@gmail.com>
Subject: Re: [PATCH v3 3/4] daemon: use sigaction() to install child_handler()
Date: Thu, 26 Jun 2025 14:11:52 +0100 [thread overview]
Message-ID: <d7c86948-e0b0-4864-88f8-fd1222e0dffe@gmail.com> (raw)
In-Reply-To: <c66bda461f45791d278779fb0021f1e0369fe889.1750927989.git.gitgitgadget@gmail.com>
Hi Carlo
On 26/06/2025 09:53, Carlo Marcelo Arenas Belón via GitGitGadget wrote:
> From: =?UTF-8?q?Carlo=20Marcelo=20Arenas=20Bel=C3=B3n?= <carenas@gmail.com>
>
> In a future change, the flags used for processing SIGCHLD will need to
> be updated, which is only possible by using sigaction().
Only because you have chosen to use SA_RESTART here. I think it would be
better to drop that and instead say something like
POSIX leaves several aspects of the behavior of signal() up to the
implementer. It is unspecified whether long running syscalls are
restarted after an interrupt is received. The event loop in "git
daemon" assumes that poll() will return with EINTR if a child exits
while it is polling but if poll() is restarted after an interrupt is
received that does not happen which can lead to a build up of
uncollected zombie processes.
It is also unspecified whether the handler is reset after an interrupt
is received. In order to work correctly on operating systems such as
Solaris where the handler for SIGCLD is reset when a signal is received
"git daemon" calls signal() from the SIGCLD handler to re-establish a
handler for that signal. Unfortunately this causes infinite recursion on
other operating systems such as AIX.
Both of these problems can be addressed by using sigaction() instead of
signal() which has much stricter semantics and so, by setting the
appropriate flags, we can rely on poll() being interrupted and the
SIGCLD handler not being reset. This change means that all long running
system calls could fail with EINTR not just pall() but rest of the event
loop code is designed to gracefully handle that.
After this change there is still a race where a child that exits after
it has been checked in check_dead_children() but before we call poll()
will not be collected until a new connection is received or a child
exits while we're polling. We could fix this by using the "self-pipe
trick" but do not because ....
Then we can drop patches 1 and 4.
Best Wishes
Phillip
>
> Replace signal() with an equivalent invocation of sigaction(), which
> has the added benefit of using BSD semantics reliably and therefore
> not needing the rearming call in the signal handler.
>
> Signed-off-by: Carlo Marcelo Arenas Belón <carenas@gmail.com>
> ---
> daemon.c | 12 +++++++-----
> 1 file changed, 7 insertions(+), 5 deletions(-)
>
> diff --git a/daemon.c b/daemon.c
> index d1be61fd5789..155b2e180167 100644
> --- a/daemon.c
> +++ b/daemon.c
> @@ -915,11 +915,9 @@ static void handle(int incoming, struct sockaddr *addr, socklen_t addrlen)
> static void child_handler(int signo UNUSED)
> {
> /*
> - * Otherwise empty handler because systemcalls will get interrupted
> - * upon signal receipt
> - * SysV needs the handler to be rearmed
> + * Otherwise empty handler because systemcalls should get interrupted
> + * upon signal receipt.
> */
> - signal(SIGCHLD, child_handler);
> }
>
> static int set_reuse_addr(int sockfd)
> @@ -1120,6 +1118,7 @@ static void socksetup(struct string_list *listen_addr, int listen_port, struct s
>
> static int service_loop(struct socketlist *socklist)
> {
> + struct sigaction sa;
> struct pollfd *pfd;
>
> CALLOC_ARRAY(pfd, socklist->nr);
> @@ -1129,7 +1128,10 @@ static int service_loop(struct socketlist *socklist)
> pfd[i].events = POLLIN;
> }
>
> - signal(SIGCHLD, child_handler);
> + sigemptyset(&sa.sa_mask);
> + sa.sa_flags = SA_NOCLDSTOP | SA_RESTART;
> + sa.sa_handler = child_handler;
> + sigaction(SIGCHLD, &sa, NULL);
>
> for (;;) {
> check_dead_children();
next prev parent reply other threads:[~2025-06-26 13:11 UTC|newest]
Thread overview: 70+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-06-24 14:08 [PATCH 0/3] daemon: explicitly allow EINTR during poll() Carlo Marcelo Arenas Belón via GitGitGadget
2025-06-24 14:08 ` [PATCH 1/3] compat/posix.h: track SA_RESTART fallback Carlo Marcelo Arenas Belón via GitGitGadget
2025-06-24 15:34 ` Junio C Hamano
2025-06-24 16:28 ` Junio C Hamano
2025-06-24 14:08 ` [PATCH 2/3] daemon: use sigaction() to install child_handler() Carlo Marcelo Arenas Belón via GitGitGadget
2025-06-24 15:37 ` Junio C Hamano
2025-06-24 22:29 ` Carlo Marcelo Arenas Belón
2025-06-24 23:27 ` Chris Torek
2025-06-24 16:20 ` Junio C Hamano
2025-06-24 21:28 ` Carlo Marcelo Arenas Belón
2025-06-24 21:32 ` Junio C Hamano
2025-06-24 14:08 ` [PATCH 3/3] daemon: explicitly allow EINTR during poll() Carlo Marcelo Arenas Belón via GitGitGadget
2025-06-24 14:33 ` Carlo Marcelo Arenas Belón
2025-06-24 15:43 ` Junio C Hamano
2025-06-25 7:35 ` [PATCH v2 0/3] " Carlo Marcelo Arenas Belón via GitGitGadget
2025-06-25 7:35 ` [PATCH v2 1/3] compat/posix.h: track SA_RESTART fallback Carlo Marcelo Arenas Belón via GitGitGadget
2025-06-25 16:07 ` Junio C Hamano
2025-06-25 22:24 ` Carlo Marcelo Arenas Belón
2025-06-26 0:33 ` Junio C Hamano
2025-06-26 1:35 ` Carlo Marcelo Arenas Belón
2025-06-26 0:45 ` Junio C Hamano
2025-06-25 7:35 ` [PATCH v2 2/3] daemon: use sigaction() to install child_handler() Carlo Marcelo Arenas Belón via GitGitGadget
2025-06-25 16:06 ` Junio C Hamano
2025-06-25 16:22 ` Junio C Hamano
2025-06-25 7:35 ` [PATCH v2 3/3] daemon: explicitly allow EINTR during poll() Carlo Marcelo Arenas Belón via GitGitGadget
2025-06-25 16:11 ` Junio C Hamano
2025-06-25 8:39 ` [PATCH v2 0/3] " Phillip Wood
2025-06-25 16:24 ` Junio C Hamano
2025-06-25 19:35 ` Phillip Wood
2025-06-26 18:24 ` [RFC PATCH] daemon: add a self pipe to trigger reaping of children Carlo Marcelo Arenas Belón
2025-06-26 21:22 ` [RFC PATCH 0/2] daemon: tracking childs without signals Carlo Marcelo Arenas Belón
2025-06-26 21:22 ` [RFC PATCH 1/2] run-command: add a pipe() write end to childs Carlo Marcelo Arenas Belón
2025-06-26 21:22 ` [RFC PATCH 2/2] daemon: poor man's pidfd like POC Carlo Marcelo Arenas Belón
2025-06-27 8:38 ` [RFC PATCH] daemon: add a self pipe to trigger reaping of children Phillip Wood
2025-06-28 6:19 ` Carlo Marcelo Arenas Belón
2025-07-01 13:38 ` Phillip Wood
2025-06-30 15:16 ` Junio C Hamano
2025-06-25 16:07 ` [PATCH v2 0/3] daemon: explicitly allow EINTR during poll() Junio C Hamano
2025-06-26 8:50 ` Carlo Marcelo Arenas Belón
2025-06-26 8:53 ` [PATCH v3 0/4] " Carlo Marcelo Arenas Belón via GitGitGadget
2025-06-26 8:53 ` [PATCH v3 1/4] compat/posix.h: track SA_RESTART fallback Carlo Marcelo Arenas Belón via GitGitGadget
2025-06-27 1:41 ` Junio C Hamano
2025-06-26 8:53 ` [PATCH v3 2/4] compat/mingw: allow sigaction(SIGCHLD) Carlo Marcelo Arenas Belón via GitGitGadget
2025-06-26 12:52 ` Phillip Wood
2025-06-26 13:15 ` Carlo Marcelo Arenas Belón
2025-06-26 13:56 ` Phillip Wood
2025-06-26 14:58 ` Carlo Marcelo Arenas Belón
2025-06-26 15:19 ` phillip.wood123
2025-06-26 20:09 ` Carlo Marcelo Arenas Belón
2025-07-09 14:13 ` Phillip Wood
2025-07-09 16:36 ` Carlo Marcelo Arenas Belón
2025-06-26 8:53 ` [PATCH v3 3/4] daemon: use sigaction() to install child_handler() Carlo Marcelo Arenas Belón via GitGitGadget
2025-06-26 13:11 ` Phillip Wood [this message]
2025-06-26 15:33 ` Junio C Hamano
2025-06-26 16:36 ` Carlo Marcelo Arenas Belón
2025-06-26 18:04 ` Phillip Wood
2025-07-07 22:14 ` Junio C Hamano
2025-06-26 8:53 ` [PATCH v3 4/4] daemon: explicitly allow EINTR during poll() Carlo Marcelo Arenas Belón via GitGitGadget
2025-06-26 13:14 ` Phillip Wood
2025-07-09 14:12 ` [PATCH v3 0/4] " Phillip Wood
2025-07-09 17:04 ` Carlo Marcelo Arenas Belón
2025-07-10 19:45 ` [PATCH v4 0/2] " Carlo Marcelo Arenas Belón via GitGitGadget
2025-07-10 19:45 ` [PATCH v4 1/2] compat/mingw: allow sigaction(SIGCHLD) Carlo Marcelo Arenas Belón via GitGitGadget
2025-07-10 21:38 ` Eric Sunshine
2025-07-10 19:45 ` [PATCH v4 2/2] daemon: use sigaction() to install child_handler() Carlo Marcelo Arenas Belón via GitGitGadget
2025-07-10 21:26 ` [PATCH v4 0/2] daemon: explicitly allow EINTR during poll() Junio C Hamano
2025-07-10 23:18 ` Carlo Arenas
2025-07-11 13:14 ` Phillip Wood
2025-07-14 21:52 ` Junio C Hamano
2025-07-15 9:29 ` Phillip Wood
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=d7c86948-e0b0-4864-88f8-fd1222e0dffe@gmail.com \
--to=phillip.wood123@gmail.com \
--cc=carenas@gmail.com \
--cc=chris.torek@gmail.com \
--cc=git@vger.kernel.org \
--cc=gitgitgadget@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).