Skip to content

Commit

Permalink
git daemon: avoid calling syslog() from a signal handler
Browse files Browse the repository at this point in the history
Signal handlers should never call syslog(), as that can raise signals
of its own.

Instead, call the syslog() from the master process.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
  • Loading branch information
Johannes Schindelin authored and Junio C Hamano committed Jul 7, 2008
1 parent 182c5af commit a5a9126
Showing 1 changed file with 50 additions and 20 deletions.
70 changes: 50 additions & 20 deletions daemon.c
Original file line number Diff line number Diff line change
Expand Up @@ -694,23 +694,47 @@ static void kill_some_children(int signo, unsigned start, unsigned stop)
}
}

static void check_dead_children(void)
{
unsigned spawned, reaped, deleted;

spawned = children_spawned;
reaped = children_reaped;
deleted = children_deleted;

while (deleted < reaped) {
pid_t pid = dead_child[deleted % MAX_CHILDREN];
const char *dead = pid < 0 ? " (with error)" : "";

if (pid < 0)
pid = -pid;

/* XXX: Custom logging, since we don't wanna getpid() */
if (verbose) {
if (log_syslog)
syslog(LOG_INFO, "[%d] Disconnected%s",
pid, dead);
else
fprintf(stderr, "[%d] Disconnected%s\n",
pid, dead);
}
remove_child(pid, deleted, spawned);
deleted++;
}
children_deleted = deleted;
}

static void check_max_connections(void)
{
for (;;) {
int active;
unsigned spawned, reaped, deleted;
unsigned spawned, deleted;

check_dead_children();

spawned = children_spawned;
reaped = children_reaped;
deleted = children_deleted;

while (deleted < reaped) {
pid_t pid = dead_child[deleted % MAX_CHILDREN];
remove_child(pid, deleted, spawned);
deleted++;
}
children_deleted = deleted;

active = spawned - deleted;
if (active <= max_connections)
break;
Expand Down Expand Up @@ -760,18 +784,10 @@ static void child_handler(int signo)

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;
/* XXX: Custom logging, since we don't wanna getpid() */
if (verbose) {
const char *dead = "";
if (!WIFEXITED(status) || WEXITSTATUS(status) > 0)
dead = " (with error)";
if (log_syslog)
syslog(LOG_INFO, "[%d] Disconnected%s", pid, dead);
else
fprintf(stderr, "[%d] Disconnected%s\n", pid, dead);
}
continue;
}
break;
Expand Down Expand Up @@ -928,15 +944,29 @@ static int service_loop(int socknum, int *socklist)

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

if (poll(pfd, socknum, -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) {
error("poll failed, resuming: %s",
strerror(errno));
sleep(1);
}
continue;
}
if (i == 0) {
check_dead_children();
continue;
}

for (i = 0; i < socknum; i++) {
if (pfd[i].revents & POLLIN) {
Expand Down

0 comments on commit a5a9126

Please sign in to comment.