diff options
author | Linus Torvalds <torvalds@g5.osdl.org> | 2005-07-15 20:42:28 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2005-07-15 20:42:28 -0700 |
commit | eaa9491955ef645bd2d3ca989f17bb80b9896d23 (patch) | |
tree | fd1bd025fa8057fa29e7bd26bed21b711dab27cf /daemon.c | |
parent | 78d9d414123ad6f4f522ffecbcd9e4a7562948fd (diff) | |
download | git-eaa9491955ef645bd2d3ca989f17bb80b9896d23.tar.gz |
git-daemon: keep track of children
We don't want them as zombies, and eventually we'll want to limit their
number. Right now we just count them.
Diffstat (limited to 'daemon.c')
-rw-r--r-- | daemon.c | 44 |
1 files changed, 43 insertions, 1 deletions
@@ -1,10 +1,24 @@ #include "cache.h" #include "pkt-line.h" +#include <signal.h> +#include <sys/wait.h> #include <sys/socket.h> #include <netinet/in.h> static const char daemon_usage[] = "git-daemon [--inetd | --port=n]"; +/* We don't actually do anything about this yet */ +static int max_connections = 10; + +/* + * We count spawned/reaped separately, just to avoid any + * races when updating them from signals. The SIGCHLD handler + * will only update children_reaped, and the fork logic will + * only update children_spawned. + */ +static unsigned int children_spawned = 0; +static unsigned int children_reaped = 0; + static int upload(char *dir, int dirlen) { if (chdir(dir) < 0) @@ -47,8 +61,24 @@ static int execute(void) static void handle(int incoming, struct sockaddr_in *addr, int addrlen) { - if (fork()) { + pid_t pid = fork(); + + if (pid) { + int active; + close(incoming); + if (pid < 0) + return; + + active = ++children_spawned - children_reaped; + if (active > max_connections) { + /* + * Fixme! This is where you'd have to do something to + * limit the number of children. Like killing off random + * ones, or at least the ones that haven't even gotten + * started yet. + */ + } return; } @@ -58,11 +88,23 @@ static void handle(int incoming, struct sockaddr_in *addr, int addrlen) exit(execute()); } +static void child_handler(int signo) +{ + for (;;) { + if (waitpid(-1, NULL, WNOHANG) > 0) { + children_reaped++; + continue; + } + break; + } +} + static int serve(int port) { int sockfd; struct sockaddr_in addr; + signal(SIGCHLD, child_handler); sockfd = socket(PF_INET, SOCK_STREAM, IPPROTO_IP); if (sockfd < 0) die("unable to open socket (%s)", strerror(errno)); |