git: plan9front

Download patch

ref: 733dab56a1ed746faaf875f61ecf1258331f63d2
parent: 2524319b4ce7f98d0d61a400ccbcfbd55eaf4098
author: cinap_lenrek <cinap_lenrek@centraldogma>
date: Mon Dec 12 05:08:02 EST 2011

listen1: add process limit option

--- a/sys/man/8/listen
+++ b/sys/man/8/listen
@@ -18,6 +18,8 @@
 [
 .B -tv
 ]
+.RB [ -p
+.IR maxprocs ]
 .I addr
 .I cmd
 [
--- a/sys/src/cmd/aux/listen1.c
+++ b/sys/src/cmd/aux/listen1.c
@@ -2,6 +2,7 @@
 #include <libc.h>
 #include <auth.h>
 
+int maxprocs;
 int verbose;
 int trusted;
 
@@ -8,7 +9,7 @@
 void
 usage(void)
 {
-	fprint(2, "usage: listen1 [-tv] address cmd args...\n");
+	fprint(2, "usage: listen1 [-tv] [-p maxprocs] address cmd args...\n");
 	exits("usage");
 }
 
@@ -51,8 +52,10 @@
 void
 main(int argc, char **argv)
 {
-	char data[60], dir[40], ndir[40];
+	char data[60], dir[40], ndir[40], wbuf[64];
 	int ctl, nctl, fd;
+	int wfd, nowait, procs;
+	Dir *d;
 
 	ARGBEGIN{
 	default:
@@ -63,6 +66,9 @@
 	case 'v':
 		verbose = 1;
 		break;
+	case 'p':
+		maxprocs = atoi(EARGF(usage()));
+		break;
 	}ARGEND
 
 	if(argc < 2)
@@ -85,12 +91,34 @@
 	if(ctl < 0)
 		sysfatal("announce %s: %r", argv[0]);
 
+	wfd = -1;
+	nowait = RFNOWAIT;
+	if(maxprocs > 0){
+		snprint(wbuf, sizeof(wbuf), "/proc/%d/wait", getpid());
+		if((wfd = open(wbuf, OREAD)) >= 0)
+			nowait = 0;
+	}
+	procs = 0;
 	for(;;){
+		if(nowait == 0 && (procs >= maxprocs || (procs % 8) == 0))
+			while(procs > 0){
+				if(procs < maxprocs){
+					d = dirfstat(wfd);
+					if(d == nil || d->length == 0){
+						free(d);
+						break;
+					}
+					free(d);
+				}
+				if(read(wfd, wbuf, sizeof(wbuf)) > 0)
+					procs--;
+			}
+
 		nctl = listen(dir, ndir);
 		if(nctl < 0)
 			sysfatal("listen %s: %r", argv[0]);
 
-		switch(rfork(RFFDG|RFPROC|RFNOWAIT|RFENVG|RFNAMEG|RFNOTEG)){
+		switch(rfork(RFFDG|RFPROC|RFMEM|RFENVG|RFNAMEG|RFNOTEG|nowait)){
 		case -1:
 			reject(nctl, ndir, "host overloaded");
 			close(nctl);
@@ -107,6 +135,8 @@
 			fprint(nctl, "keepalive");
 			close(ctl);
 			close(nctl);
+			if(wfd >= 0)
+				close(wfd);
 			putenv("net", ndir);
 			snprint(data, sizeof data, "%s/data", ndir);
 			bind(data, "/dev/cons", MREPL);
@@ -121,6 +151,7 @@
 			exits(nil);
 		default:
 			close(nctl);
+			procs++;
 			break;
 		}
 	}
--