git daemon: avoid waking up too often

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>
maint
Johannes Schindelin 2008-07-22 23:03:01 +01:00 committed by Junio C Hamano
parent 3b6aeb3cc3
commit f9bbefc701
1 changed files with 11 additions and 14 deletions

View File

@ -16,6 +16,7 @@
static int log_syslog; static int log_syslog;
static int verbose; static int verbose;
static int reuseaddr; static int reuseaddr;
static int child_handler_pipe[2];


static const char daemon_usage[] = static const char daemon_usage[] =
"git daemon [--verbose] [--syslog] [--export-all]\n" "git daemon [--verbose] [--syslog] [--export-all]\n"
@ -788,6 +789,7 @@ static void child_handler(int signo)
pid = -pid; pid = -pid;
dead_child[reaped % MAX_CHILDREN] = pid; dead_child[reaped % MAX_CHILDREN] = pid;
children_reaped = reaped + 1; children_reaped = reaped + 1;
write(child_handler_pipe[1], &status, 1);
continue; continue;
} }
break; break;
@ -933,29 +935,24 @@ static int service_loop(int socknum, int *socklist)
struct pollfd *pfd; struct pollfd *pfd;
int i; 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++) { for (i = 0; i < socknum; i++) {
pfd[i].fd = socklist[i]; pfd[i].fd = socklist[i];
pfd[i].events = POLLIN; pfd[i].events = POLLIN;
} }
pfd[socknum].fd = child_handler_pipe[0];
pfd[socknum].events = POLLIN;


signal(SIGCHLD, child_handler); signal(SIGCHLD, child_handler);


for (;;) { for (;;) {
int i; int i;
int timeout;


/* if (poll(pfd, socknum + 1, -1) < 0) {
* 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 (errno != EINTR) { if (errno != EINTR) {
error("poll failed, resuming: %s", error("poll failed, resuming: %s",
strerror(errno)); strerror(errno));
@ -963,9 +960,9 @@ static int service_loop(int socknum, int *socklist)
} }
continue; continue;
} }
if (i == 0) { if (pfd[socknum].revents & POLLIN) {
read(child_handler_pipe[0], &i, 1);
check_dead_children(); check_dead_children();
continue;
} }


for (i = 0; i < socknum; i++) { for (i = 0; i < socknum; i++) {