diff options
author | cinap_lenrek <cinap_lenrek@gmx.de> | 2012-03-30 19:07:50 +0200 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@gmx.de> | 2012-03-30 19:07:50 +0200 |
commit | d9f65faf71ff09a3427309f8b69500280c481ac6 (patch) | |
tree | e4c1eddf7bdc1769a786723cd9af5b409016a4ac /sys/src/cmd/webfs | |
parent | f000760ec0970b7f9d5e61ba556f7e3b6aecf703 (diff) |
webfs: close idle connections after 5 seconds
Diffstat (limited to 'sys/src/cmd/webfs')
-rw-r--r-- | sys/src/cmd/webfs/http.c | 66 |
1 files 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; @@ -105,6 +112,19 @@ hdial(Url *u) } 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 @@ 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; } |