Andrew's git
/
gitweb.git
/ diff
summary
|
log
|
commit
| diff |
tree
commit
grep
author
committer
pickaxe
?
re
git-daemon: keep track of children
author
Linus Torvalds
<torvalds@g5.osdl.org>
Sat, 16 Jul 2005 03:42:28 +0000
(20:42 -0700)
committer
Linus Torvalds
<torvalds@g5.osdl.org>
Sat, 16 Jul 2005 03:42:28 +0000
(20:42 -0700)
We don't want them as zombies, and eventually we'll want to limit their
number. Right now we just count them.
daemon.c
patch
|
blob
|
history
raw
|
patch
|
inline
| side by side (parent:
78d9d41
)
diff --git
a/daemon.c
b/daemon.c
index 74a1934dc2f1746a0985331eab26bb2ce53d3af3..e6fbab6bc9d6b0c2358841b0ca3b821b8a68189b 100644
(file)
--- a/
daemon.c
+++ b/
daemon.c
@@
-1,10
+1,24
@@
#include "cache.h"
#include "pkt-line.h"
#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]";
#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)
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)
{
static void handle(int incoming, struct sockaddr_in *addr, int addrlen)
{
- if (fork()) {
+ pid_t pid = fork();
+
+ if (pid) {
+ int active;
+
close(incoming);
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;
}
return;
}
@@
-58,11
+88,23
@@
static void handle(int incoming, struct sockaddr_in *addr, int addrlen)
exit(execute());
}
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;
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));
sockfd = socket(PF_INET, SOCK_STREAM, IPPROTO_IP);
if (sockfd < 0)
die("unable to open socket (%s)", strerror(errno));