git daemon: avoid waking up too often
authorJohannes Schindelin <Johannes.Schindelin@gmx.de>
Tue, 22 Jul 2008 22:03:01 +0000 (23:03 +0100)
committerJunio C Hamano <gitster@pobox.com>
Wed, 23 Jul 2008 23:57:14 +0000 (16:57 -0700)
To avoid waking up unnecessarily, a pipe is set up that is only ever
written to by child_handler(), when a child disconnects, as suggested
per Junio.

This avoids waking up the main process every second to see if a child
was disconnected.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
daemon.c

index 7df41a6a49359f31991d383f73b8d9cb11e992a9..4540e8df5ab8bc8ff66549144d7db2928e12199b 100644 (file)
--- a/daemon.c
+++ b/daemon.c
@@ -16,6 +16,7 @@
 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"
@@ -788,6 +789,7 @@ static void child_handler(int signo)
                                pid = -pid;
                        dead_child[reaped % MAX_CHILDREN] = pid;
                        children_reaped = reaped + 1;
+                       write(child_handler_pipe[1], &status, 1);
                        continue;
                }
                break;
@@ -933,29 +935,24 @@ static int service_loop(int socknum, int *socklist)
        struct pollfd *pfd;
        int i;
 
-       pfd = xcalloc(socknum, sizeof(struct pollfd));
+       if (pipe(child_handler_pipe) < 0)
+               die ("Could not set up pipe for child handler");
+
+       pfd = xcalloc(socknum + 1, 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;
 
        signal(SIGCHLD, child_handler);
 
        for (;;) {
                int i;
-               int timeout;
 
-               /*
-                * This 1-sec timeout could lead to idly looping but it is
-                * here so that children culled in child_handler() are reported
-                * without too much delay.  We could probably set up a pipe
-                * to ourselves that we poll, and write to the fd from child_handler()
-                * to wake us up (and consume it when the poll() returns...
-                */
-               timeout = (children_spawned != children_deleted) ? 1000 : -1;
-               i = poll(pfd, socknum, timeout);
-               if (i < 0) {
+               if (poll(pfd, socknum + 1, -1) < 0) {
                        if (errno != EINTR) {
                                error("poll failed, resuming: %s",
                                      strerror(errno));
@@ -963,9 +960,9 @@ static int service_loop(int socknum, int *socklist)
                        }
                        continue;
                }
-               if (i == 0) {
+               if (pfd[socknum].revents & POLLIN) {
+                       read(child_handler_pipe[0], &i, 1);
                        check_dead_children();
-                       continue;
                }
 
                for (i = 0; i < socknum; i++) {