webfs: close idle connections after 5 seconds

This commit is contained in:
cinap_lenrek 2012-03-30 19:07:50 +02:00
parent f000760ec0
commit d9f65faf71

View file

@ -19,6 +19,7 @@ typedef struct Hauth Hauth;
struct Hconn struct Hconn
{ {
Hconn *next; Hconn *next;
long time;
int fd; int fd;
int keep; int keep;
@ -34,7 +35,9 @@ struct Hpool
Hconn *head; Hconn *head;
int active; int active;
int limit; int limit;
int idle;
}; };
struct Hauth struct Hauth
@ -46,11 +49,14 @@ struct Hauth
static Hpool hpool = { static Hpool hpool = {
.limit = 16, .limit = 16,
.idle = 5, /* seconds */
}; };
static QLock authlk; static QLock authlk;
static Hauth *hauth; static Hauth *hauth;
static void hclose(Hconn *h);
static Hconn* static Hconn*
hdial(Url *u) hdial(Url *u)
{ {
@ -95,6 +101,7 @@ hdial(Url *u)
h = emalloc(sizeof(*h)); h = emalloc(sizeof(*h));
h->next = nil; h->next = nil;
h->time = 0;
h->cancel = 0; h->cancel = 0;
h->keep = 1; h->keep = 1;
h->len = 0; h->len = 0;
@ -104,6 +111,19 @@ hdial(Url *u)
return h; 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 static void
hclose(Hconn *h) hclose(Hconn *h)
{ {
@ -123,6 +143,7 @@ hclose(Hconn *h)
} }
if(x == nil){ if(x == nil){
/* return connection to pool */ /* return connection to pool */
h->time = time(0);
h->next = hpool.head; h->next = hpool.head;
hpool.head = h; hpool.head = h;
@ -131,14 +152,49 @@ hclose(Hconn *h)
x = t->next; x = t->next;
t->next = nil; t->next = nil;
} }
i = h->next != nil;
qunlock(&hpool); qunlock(&hpool);
/* free the tail */ /* free the tail */
while(h = x){ hcloseall(x);
x = h->next;
h->next = nil; /*
h->keep = 0; * if h is first one in pool, spawn proc to close
hclose(h); * 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; return;
} }