THIS IS A TEST INSTANCE ONLY! REPOSITORIES CAN BE DELETED AT ANY TIME!

Browse Source

git daemon: avoid calling syslog() from a signal handler

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>
tags/v1.5.6.4
Johannes Schindelin Junio C Hamano 11 years ago
parent
commit
a5a9126bb4
1 changed files with 50 additions and 20 deletions
  1. +50
    -20
      daemon.c

+ 50
- 20
daemon.c View File

@@ -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;
@@ -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;
@@ -928,8 +944,18 @@ 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));
@@ -937,6 +963,10 @@ static int service_loop(int socknum, int *socklist)
}
continue;
}
if (i == 0) {
check_dead_children();
continue;
}

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


Loading…
Cancel
Save