X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=daemon.c;h=8dcde73200d1ddbc0dec0dbfdc2f4ff15047abd9;hb=16cccd8bff6c0cf2700b169215a831ac63d6b145;hp=ce3a6f58f3c5c6bb88617510422c4053e0d545a2;hpb=013942f637e2e0706b5a44e58a9d285bc57c5305;p=git.git diff --git a/daemon.c b/daemon.c index ce3a6f58f..8dcde7320 100644 --- a/daemon.c +++ b/daemon.c @@ -16,9 +16,10 @@ 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" +"git daemon [--verbose] [--syslog] [--export-all]\n" " [--timeout=n] [--init-timeout=n] [--strict-paths]\n" " [--base-path=path] [--base-path-relaxed]\n" " [--user-path | --user-path=path]\n" @@ -788,10 +789,12 @@ 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; } + signal(SIGCHLD, child_handler); } static int set_reuse_addr(int sockfd) @@ -933,29 +936,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 +961,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++) {