summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: a232a13)
raw | patch | inline | side by side (parent: a232a13)
author | Linus Torvalds <torvalds@g5.osdl.org> | |
Sat, 16 Jul 2005 05:53:31 +0000 (22:53 -0700) | ||
committer | Linus Torvalds <torvalds@g5.osdl.org> | |
Sat, 16 Jul 2005 05:53:31 +0000 (22:53 -0700) |
Shut down connections that haven't even identified themselves as git
clients first. That should get rid of people who just connect to the
port and wait for something to happen.
clients first. That should get rid of people who just connect to the
port and wait for something to happen.
daemon.c | patch | blob | history |
diff --git a/daemon.c b/daemon.c
index 32196156bf9776af75c9adfcaacbef44cad13651..0ae9af0ad4d6c58d8c7cc0b615d8f9a7bc75572c 100644 (file)
--- a/daemon.c
+++ b/daemon.c
access("HEAD", R_OK))
return -1;
+ /*
+ * We'll ignore SIGTERM from now on, we have a
+ * good client.
+ */
+ signal(SIGTERM, SIG_IGN);
+
/* git-upload-pack only ever reads stuff, so this is safe */
execlp("git-upload-pack", "git-upload-pack", ".", NULL);
return -1;
*
* Really, this is just a place-holder for a _real_ algorithm.
*/
-static void kill_some_children(int connections, unsigned start, unsigned stop)
+static void kill_some_children(int signo, unsigned start, unsigned stop)
{
start %= MAX_CHILDREN;
stop %= MAX_CHILDREN;
while (start != stop) {
if (!(start & 3))
- kill(live_child[start].pid, SIGTERM);
+ kill(live_child[start].pid, signo);
start = (start + 1) % MAX_CHILDREN;
}
}
-static void handle(int incoming, struct sockaddr_in *addr, int addrlen)
+static void check_max_connections(void)
{
- pid_t pid = fork();
-
- if (pid) {
+ for (;;) {
int active;
unsigned spawned, reaped, deleted;
- close(incoming);
- if (pid < 0)
- return;
-
spawned = children_spawned;
- add_child(spawned % MAX_CHILDREN, pid, addr, addrlen);
- children_spawned = ++spawned;
-
reaped = children_reaped;
deleted = children_deleted;
children_deleted = deleted;
active = spawned - deleted;
- if (active > max_connections) {
- kill_some_children(active, deleted, spawned);
+ if (active <= max_connections)
+ break;
- /* Wait to make sure they're gone */
- while (spawned - children_reaped > max_connections)
- sleep(1);
- }
-
+ /* Kill some unstarted connections with SIGTERM */
+ kill_some_children(SIGTERM, deleted, spawned);
+ if (active <= max_connections << 1)
+ break;
+
+ /* If the SIGTERM thing isn't helping use SIGKILL */
+ kill_some_children(SIGKILL, deleted, spawned);
+ sleep(1);
+ }
+}
+
+static void handle(int incoming, struct sockaddr_in *addr, int addrlen)
+{
+ pid_t pid = fork();
+
+ if (pid) {
+ unsigned idx;
+
+ close(incoming);
+ if (pid < 0)
+ return;
+
+ idx = children_spawned % MAX_CHILDREN;
+ children_spawned++;
+ add_child(idx, pid, addr, addrlen);
+ check_max_connections();
return;
}