From d9f65faf71ff09a3427309f8b69500280c481ac6 Mon Sep 17 00:00:00 2001 From: cinap_lenrek Date: Fri, 30 Mar 2012 19:07:50 +0200 Subject: [PATCH] webfs: close idle connections after 5 seconds --- sys/src/cmd/webfs/http.c | 66 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 61 insertions(+), 5 deletions(-) diff --git a/sys/src/cmd/webfs/http.c b/sys/src/cmd/webfs/http.c index 04724268d..2db354dde 100644 --- a/sys/src/cmd/webfs/http.c +++ b/sys/src/cmd/webfs/http.c @@ -19,6 +19,7 @@ typedef struct Hauth Hauth; struct Hconn { Hconn *next; + long time; int fd; int keep; @@ -34,7 +35,9 @@ struct Hpool Hconn *head; int active; + int limit; + int idle; }; struct Hauth @@ -46,11 +49,14 @@ struct Hauth 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 @@ hdial(Url *u) h = emalloc(sizeof(*h)); h->next = nil; + h->time = 0; h->cancel = 0; h->keep = 1; h->len = 0; @@ -104,6 +111,19 @@ hdial(Url *u) return h; } +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) { @@ -123,6 +143,7 @@ hclose(Hconn *h) } if(x == nil){ /* return connection to pool */ + h->time = time(0); h->next = hpool.head; hpool.head = h; @@ -131,14 +152,49 @@ hclose(Hconn *h) 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; }