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

[PATCH 2/3] git-daemon: make the signal handler almost a no-op

From
Stephen R. van den Berg <srb@cuci.nl>
Date
Aug 13, 2008, 08:43 UTC
Message-ID
<20080813084331.30845.74788.stgit@aristoteles.cuci.nl>
In-Reply-To
<20080813084330.30845.89753.stgit@aristoteles.cuci.nl>

by exploiting the fact that systemcalls get interrupted by signals; and even they aren't, all zombies will be collected before the next accept(). Fix another error() -> logerror() call.

Signed-off-by: Stephen R. van den Berg <srb@cuci.nl>
---
 daemon.c |   67 +++++++++++++++++++++++++++++---------------------------------
 1 files changed, 31 insertions(+), 36 deletions(-)
diff --git a/daemon.c b/daemon.c
index 774b2ce..19d620c 100644
--- a/daemon.c
+++ b/daemon.c
@@ -16,7 +16,6 @@
 static int log_syslog;
 static int verbose;
 static int reuseaddr;
-static int child_handler_pipe[2];
 
 static const char daemon_usage[] =
 "git daemon [--verbose] [--syslog] [--export-all]\n"
@@ -680,6 +679,21 @@ static void check_dead_children(void)
 {
 	unsigned spawned, reaped, deleted;
 
+	for (;;) {
+	    int status;
+	    pid_t pid = waitpid(-1, &status, WNOHANG);
+	
+	    if (pid > 0) {
+	        unsigned reaped = children_reaped;
+	        if (!WIFEXITED(status) || WEXITSTATUS(status) > 0)
+	            pid = -pid;
+	        dead_child[reaped % MAX_CHILDREN] = pid;
+	        children_reaped = reaped + 1;
+	        continue;
+	    }
+	    break;
+	}
+
 	spawned = children_spawned;
 	reaped = children_reaped;
 	deleted = children_deleted;
@@ -760,21 +774,10 @@ static void handle(int incoming, struct sockaddr *addr, int addrlen)
 
 static void child_handler(int signo)
 {
-	for (;;) {
-		int status;
-		pid_t pid = waitpid(-1, &status, WNOHANG);
-
-		if (pid > 0) {
-			unsigned reaped = children_reaped;
-			if (!WIFEXITED(status) || WEXITSTATUS(status) > 0)
-				pid = -pid;
-			dead_child[reaped % MAX_CHILDREN] = pid;
-			children_reaped = reaped + 1;
-			write(child_handler_pipe[1], &status, 1);
-			continue;
-		}
-		break;
-	}
+	/* Otherwise empty handler because systemcalls will get interrupted
+	 * upon signal receipt
+	 * SysV needs the handler to be reinstated
+	 */
 	signal(SIGCHLD, child_handler);
 }
 
@@ -917,35 +920,30 @@ static int service_loop(int socknum, int *socklist)
 	struct pollfd *pfd;
 	int i;
 
-	if (pipe(child_handler_pipe) < 0)
-		die ("Could not set up pipe for child handler");
-
-	pfd = xcalloc(socknum + 1, sizeof(struct pollfd));
+	pfd = xcalloc(socknum, sizeof(struct pollfd));
 
 	for (i = 0; i < socknum; i++) {
 		pfd[i].fd = socklist[i];
 		pfd[i].events = POLLIN;
 	}
-	pfd[socknum].fd = child_handler_pipe[0];
-	pfd[socknum].events = POLLIN;
-
-	child_handler(0);
 
 	for (;;) {
 		int i;
+		int olderrno;
 
-		if (poll(pfd, socknum + 1, -1) < 0) {
-			if (errno != EINTR) {
-				error("poll failed, resuming: %s",
-				      strerror(errno));
+		i = poll(pfd, socknum, -1);
+		olderrno = errno;
+
+		check_dead_children();
+
+		if (i < 0) {
+			if (olderrno != EINTR) {
+				logerror("poll failed, resuming: %s",
+				      strerror(olderrno));
 				sleep(1);
 			}
 			continue;
 		}
-		if (pfd[socknum].revents & POLLIN) {
-			read(child_handler_pipe[0], &i, 1);
-			check_dead_children();
-		}
 
 		for (i = 0; i < socknum; i++) {
 			if (pfd[i].revents & POLLIN) {
@@ -1036,10 +1034,7 @@ int main(int argc, char **argv)
 	gid_t gid = 0;
 	int i;
 
-	/* Without this we cannot rely on waitpid() to tell
-	 * what happened to our children.
-	 */
-	signal(SIGCHLD, SIG_DFL);
+	child_handler(0);
 
 	for (i = 1; i < argc; i++) {
 		char *arg = argv[i];
Previous: Stephen R. van den BergNext: Junio C Hamano
Message 8 of 16 in “git-daemon: logging done right”
  1. 1/3 git-daemon: logging done rightStephen R. van den Berg, Aug 13, 2008
  2. 3/3 git-daemon: rewrite kindergardenStephen R. van den Berg, Aug 13, 2008
  3. Stephen R. van den BergAug 13, 2008
  4. git-daemon: rewrite kindergardenStephen R. van den Berg, Aug 13, 2008
  5. git-daemon: rewrite kindergarden, new option --max-connectionsStephen R. van den Berg, Aug 13, 2008
  6. Petr BaudisAug 13, 2008
  7. Stephen R. van den BergAug 13, 2008
  8. 2/3 git-daemon: make the signal handler almost a no-opStephen R. van den Berg, Aug 13, 2008
  9. Junio C HamanoAug 14, 2008
  10. Stephen R. van den BergAug 14, 2008
  11. Junio C HamanoAug 14, 2008
  12. Stephen R. van den BergAug 14, 2008
  13. Junio C HamanoAug 14, 2008
  14. Stephen R. van den BergAug 14, 2008
  15. Johannes SchindelinAug 14, 2008
  16. Junio C HamanoAug 13, 2008

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.