git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH 1/2] daemon: use timeout for uninterruptible poll

From
Junio C Hamano <gitster@pobox.com>
Date
Apr 15, 2018, 21:54 UTC
Message-ID
<xmqq36zw16gv.fsf@gitster-ct.c.googlers.com>
In-Reply-To
<20180412210757.7792-2-kgybels@infogroep.be>
Kim Gybels <kgybels@infogroep.be> writes:
> The poll provided in compat/poll.c is not interrupted by receiving
> SIGCHLD. Use a timeout for cleaning up dead children in a timely manner.

I think you identified the problem and diagnosed it correctly, but I find that the change proposed here introduces a severe layering violation. The code is still calling what is called poll(), which should not have such a broken semantics.

The ideal solution would be to fix the emulation so that it also properly works for reaping a dead child process, but if that is not possible, another solution that does not break the API layering would probably be to introduce our own version of something similar to poll() that helps various platforms that cannot implement the real poll() faithfully for whatever reason. Such an xpoll() API function we introduce (and implement in compat/poll.c) may take, in addition to the usual parameters to reall poll(), the value of live_children we have at this call site. With that

 - On platforms whose poll() does work correctly for culling dead
   children will just ignore the live_children paramater in its
   implementation of xpoll()
 - On other platforms, it will shorten the timeout depending on the
   need to cull dead children, just like your patch did.
Thanks.
Show 34 quoted lines
>
> Signed-off-by: Kim Gybels <kgybels@infogroep.be>
> ---
>  daemon.c | 10 ++++++++--
>  1 file changed, 8 insertions(+), 2 deletions(-)
>
> diff --git a/daemon.c b/daemon.c
> index fe833ea7de..6dc95c1b2f 100644
> --- a/daemon.c
> +++ b/daemon.c
> @@ -1147,6 +1147,7 @@ static int service_loop(struct socketlist *socklist)
>  {
>  	struct pollfd *pfd;
>  	int i;
> +	int poll_timeout = -1;
>  
>  	pfd = xcalloc(socklist->nr, sizeof(struct pollfd));
>  
> @@ -1161,8 +1162,13 @@ static int service_loop(struct socketlist *socklist)
>  		int i;
>  
>  		check_dead_children();
> -
> -		if (poll(pfd, socklist->nr, -1) < 0) {
> +#ifdef NO_POLL
> +		poll_timeout = live_children ? 100 : -1;
> +#endif
> +		int ret = poll(pfd, socklist->nr, poll_timeout);
> +		if  (ret == 0) {
> +			continue;
> +		} else if (ret < 0) {
>  			if (errno != EINTR) {
>  				logerror("Poll failed, resuming: %s",
>  				      strerror(errno));
Previous: Johannes SchindelinNext: Junio C Hamano
Message 6 of 15 in “Fix early EOF with GfW daemon”
  1. 0/2 Fix early EOF with GfW daemonKim Gybels, Apr 12, 2018
  2. 1/2 daemon: use timeout for uninterruptible pollKim Gybels, Apr 12, 2018
  3. Johannes SchindelinApr 13, 2018
  4. Kim GybelsApr 15, 2018
  5. Johannes SchindelinApr 18, 2018
  6. Junio C HamanoApr 15, 2018
  7. Junio C HamanoApr 15, 2018
  8. Johannes SchindelinApr 18, 2018
  9. Junio C HamanoApr 18, 2018
  10. Kim GybelsApr 19, 2018
  11. Junio C HamanoApr 19, 2018
  12. 2/2 daemon: graceful shutdown of client connectionKim Gybels, Apr 12, 2018
  13. Johannes SchindelinApr 13, 2018
  14. Kim GybelsApr 15, 2018
  15. Johannes SchindelinApr 18, 2018

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.