shithub: riscv

Download patch

ref: d9f65faf71ff09a3427309f8b69500280c481ac6
parent: f000760ec0970b7f9d5e61ba556f7e3b6aecf703
author: cinap_lenrek <[email protected]>
date: Fri Mar 30 15:07:50 EDT 2012

webfs: close idle connections after 5 seconds

--- a/sys/src/cmd/webfs/http.c
+++ b/sys/src/cmd/webfs/http.c
@@ -19,6 +19,7 @@
 struct Hconn
 {
 	Hconn	*next;
+	long	time;
 
 	int	fd;
 	int	keep;
@@ -34,7 +35,9 @@
 
 	Hconn	*head;
 	int	active;
+
 	int	limit;
+	int	idle;
 };
 
 struct Hauth
@@ -46,11 +49,14 @@
 
 static Hpool hpool = {
 	.limit	= 16,
+	.idle	= 5,	/* seconds */
 };
 
 static QLock authlk;
 static Hauth *hauth;
 
+static void hclose(Hconn *h);
+
 static Hconn*
 hdial(Url *u)
 {
@@ -95,6 +101,7 @@
 
 	h = emalloc(sizeof(*h));
 	h->next = nil;
+	h->time = 0;
 	h->cancel = 0;
 	h->keep = 1;
 	h->len = 0;
@@ -105,6 +112,19 @@
 }
 
 static void
+hcloseall(Hconn *x)
+{
+	Hconn *h;
+
+	while(h = x){
+		x = h->next;
+		h->next = nil;
+		h->keep = 0;
+		hclose(h);
+	}
+}
+
+static void
 hclose(Hconn *h)
 {
 	Hconn *x, *t;
@@ -123,6 +143,7 @@
 		}
 		if(x == nil){
 			/* return connection to pool */
+			h->time = time(0);
 			h->next = hpool.head;
 			hpool.head = h;
 
@@ -131,14 +152,49 @@
 				x = t->next;
 				t->next = nil;
 			}
+
+			i = h->next != nil;
 			qunlock(&hpool);
 
 			/* free the tail */
-			while(h = x){
-				x = h->next;
-				h->next = nil;
-				h->keep = 0;
-				hclose(h);
+			hcloseall(x);
+
+			/*
+			 * if h is first one in pool, spawn proc to close
+			 * idle connections.
+			 */
+			if(i == 0)
+			if(rfork(RFMEM|RFPROC|RFNOWAIT) == 0){
+				do {
+					Hconn **xx;
+					long now;
+
+					sleep(1000);
+
+					qlock(&hpool);
+					now = time(0);
+
+					x = nil;
+					xx = &hpool.head;
+					while(h = *xx){
+						if((now - h->time) > hpool.idle){
+							*xx = h->next;
+
+							/* link to tail */
+							h->next = x;
+							x = h;
+							continue;
+						}
+						xx = &h->next;
+					}
+
+					i = hpool.head != nil;
+					qunlock(&hpool);
+
+					/* free the tail */
+					hcloseall(x);
+				} while(i);
+				exits(0);
 			}
 			return;
 		}