summaryrefslogtreecommitdiff
path: root/sys/src/cmd/webfs
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@gmx.de>2012-03-30 19:07:50 +0200
committercinap_lenrek <cinap_lenrek@gmx.de>2012-03-30 19:07:50 +0200
commitd9f65faf71ff09a3427309f8b69500280c481ac6 (patch)
treee4c1eddf7bdc1769a786723cd9af5b409016a4ac /sys/src/cmd/webfs
parentf000760ec0970b7f9d5e61ba556f7e3b6aecf703 (diff)
webfs: close idle connections after 5 seconds
Diffstat (limited to 'sys/src/cmd/webfs')
-rw-r--r--sys/src/cmd/webfs/http.c66
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;
}