Commit 78767f71 authored by Poul-Henning Kamp's avatar Poul-Henning Kamp

Give backends a reference count and reuse any existing identical backend

when a new VCL instantiates a backend.

Drop backends when their reference count goes to zero.



git-svn-id: http://www.varnish-cache.org/svn/trunk/varnish-cache@1894 d4fa192b-c00b-0410-8231-f00ffab90ce4
parent f91ea9e4
...@@ -347,12 +347,15 @@ struct backend_method { ...@@ -347,12 +347,15 @@ struct backend_method {
struct backend { struct backend {
unsigned magic; unsigned magic;
#define BACKEND_MAGIC 0x64c4c7c6 #define BACKEND_MAGIC 0x64c4c7c6
const char *vcl_name; char *vcl_name;
TAILQ_ENTRY(backend) list;
int refcount;
struct backend_method *method; struct backend_method *method;
const char *hostname; char *hostname;
const char *portname; char *portname;
struct addrinfo *addr; struct addrinfo *addr;
struct addrinfo *last_addr; struct addrinfo *last_addr;
...@@ -375,6 +378,12 @@ struct backend { ...@@ -375,6 +378,12 @@ struct backend {
}; };
/*
* NB: This list is not locked, it is only ever manipulated from the
* cachers CLI thread.
*/
TAILQ_HEAD(backendlist, backend);
/* Prototypes etc ----------------------------------------------------*/ /* Prototypes etc ----------------------------------------------------*/
...@@ -393,6 +402,9 @@ void VBE_ClosedFd(struct worker *w, struct vbe_conn *vc); ...@@ -393,6 +402,9 @@ void VBE_ClosedFd(struct worker *w, struct vbe_conn *vc);
void VBE_RecycleFd(struct worker *w, struct vbe_conn *vc); void VBE_RecycleFd(struct worker *w, struct vbe_conn *vc);
struct bereq * VBE_new_bereq(void); struct bereq * VBE_new_bereq(void);
void VBE_free_bereq(struct bereq *bereq); void VBE_free_bereq(struct bereq *bereq);
extern struct backendlist backendlist;
void VBE_DropRef(struct backend *);
struct backend *VBE_NewBackend(struct backend_method *method);
/* cache_backend_simple.c */ /* cache_backend_simple.c */
extern struct backend_method backend_method_simple; extern struct backend_method backend_method_simple;
......
...@@ -41,7 +41,9 @@ ...@@ -41,7 +41,9 @@
static TAILQ_HEAD(,bereq) bereq_head = TAILQ_HEAD_INITIALIZER(bereq_head); static TAILQ_HEAD(,bereq) bereq_head = TAILQ_HEAD_INITIALIZER(bereq_head);
static MTX vbemtx; static MTX VBE_mtx;
struct backendlist backendlist = TAILQ_HEAD_INITIALIZER(backendlist);
/*-------------------------------------------------------------------- /*--------------------------------------------------------------------
* Get a http structure for talking to the backend. * Get a http structure for talking to the backend.
...@@ -53,11 +55,11 @@ VBE_new_bereq(void) ...@@ -53,11 +55,11 @@ VBE_new_bereq(void)
struct bereq *bereq; struct bereq *bereq;
volatile unsigned len; volatile unsigned len;
LOCK(&vbemtx); LOCK(&VBE_mtx);
bereq = TAILQ_FIRST(&bereq_head); bereq = TAILQ_FIRST(&bereq_head);
if (bereq != NULL) if (bereq != NULL)
TAILQ_REMOVE(&bereq_head, bereq, list); TAILQ_REMOVE(&bereq_head, bereq, list);
UNLOCK(&vbemtx); UNLOCK(&VBE_mtx);
if (bereq != NULL) { if (bereq != NULL) {
CHECK_OBJ(bereq, BEREQ_MAGIC); CHECK_OBJ(bereq, BEREQ_MAGIC);
} else { } else {
...@@ -81,9 +83,44 @@ VBE_free_bereq(struct bereq *bereq) ...@@ -81,9 +83,44 @@ VBE_free_bereq(struct bereq *bereq)
{ {
CHECK_OBJ_NOTNULL(bereq, BEREQ_MAGIC); CHECK_OBJ_NOTNULL(bereq, BEREQ_MAGIC);
LOCK(&vbemtx); LOCK(&VBE_mtx);
TAILQ_INSERT_HEAD(&bereq_head, bereq, list); TAILQ_INSERT_HEAD(&bereq_head, bereq, list);
UNLOCK(&vbemtx); UNLOCK(&VBE_mtx);
}
/*--------------------------------------------------------------------*/
struct backend *
VBE_NewBackend(struct backend_method *method)
{
struct backend *b;
b = calloc(sizeof *b, 1);
XXXAN(b);
b->magic = BACKEND_MAGIC;
TAILQ_INIT(&b->connlist);
b->method = method;
b->refcount = 1;
TAILQ_INSERT_TAIL(&backendlist, b, list);
return (b);
}
/*--------------------------------------------------------------------*/
void
VBE_DropRef(struct backend *b)
{
CHECK_OBJ_NOTNULL(b, BACKEND_MAGIC);
b->refcount--;
if (b->refcount > 0)
return;
TAILQ_REMOVE(&backendlist, b, list);
free(b->vcl_name);
free(b->portname);
free(b->hostname);
free(b);
} }
/*--------------------------------------------------------------------*/ /*--------------------------------------------------------------------*/
...@@ -119,6 +156,6 @@ void ...@@ -119,6 +156,6 @@ void
VBE_Init(void) VBE_Init(void)
{ {
MTX_INIT(&vbemtx); MTX_INIT(&VBE_mtx);
backend_method_simple.init(); backend_method_simple.init();
} }
...@@ -520,11 +520,27 @@ VRT_init_simple_backend(struct backend **bp, struct vrt_simple_backend *t) ...@@ -520,11 +520,27 @@ VRT_init_simple_backend(struct backend **bp, struct vrt_simple_backend *t)
{ {
struct backend *b; struct backend *b;
b = calloc(sizeof *b, 1); /*
XXXAN(b); * Scan existing backends to see if we can recycle one of them.
b->magic = BACKEND_MAGIC; */
TAILQ_FOREACH(b, &backendlist, list) {
CHECK_OBJ_NOTNULL(b, BACKEND_MAGIC);
if (b->method != &backend_method_simple)
continue;
if (strcmp(b->vcl_name, t->name))
continue;
if (strcmp(b->portname, t->port))
continue;
if (strcmp(b->hostname, t->host))
continue;
b->refcount++;
*bp = b;
return;
}
b = VBE_NewBackend(&backend_method_simple);
b->dnsttl = 300; b->dnsttl = 300;
TAILQ_INIT(&b->connlist);
b->last_check = TIM_mono(); b->last_check = TIM_mono();
b->minute_limit = 1; b->minute_limit = 1;
...@@ -540,13 +556,12 @@ VRT_init_simple_backend(struct backend **bp, struct vrt_simple_backend *t) ...@@ -540,13 +556,12 @@ VRT_init_simple_backend(struct backend **bp, struct vrt_simple_backend *t)
b->hostname = strdup(t->host); b->hostname = strdup(t->host);
XXXAN(b->hostname); XXXAN(b->hostname);
b->method = &backend_method_simple;
*bp = b; *bp = b;
} }
void void
VRT_fini_backend(struct backend *b) VRT_fini_backend(struct backend *b)
{ {
(void)b;
VBE_DropRef(b);
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment