]> err.no Git - varnish/commitdiff
Give backends a reference count and reuse any existing identical backend
authorphk <phk@d4fa192b-c00b-0410-8231-f00ffab90ce4>
Mon, 20 Aug 2007 12:19:16 +0000 (12:19 +0000)
committerphk <phk@d4fa192b-c00b-0410-8231-f00ffab90ce4>
Mon, 20 Aug 2007 12:19:16 +0000 (12:19 +0000)
when a new VCL instantiates a backend.

Drop backends when their reference count goes to zero.

git-svn-id: svn+ssh://projects.linpro.no/svn/varnish/trunk@1894 d4fa192b-c00b-0410-8231-f00ffab90ce4

varnish-cache/bin/varnishd/cache.h
varnish-cache/bin/varnishd/cache_backend.c
varnish-cache/bin/varnishd/cache_vrt.c

index 158b69d630171abe9ded3e25828ac0e4ac85a87a..d6895b19f4868cb31d94a99e65435962a22d4046 100644 (file)
@@ -347,12 +347,15 @@ struct backend_method {
 struct backend {
        unsigned                magic;
 #define BACKEND_MAGIC          0x64c4c7c6
-       const char              *vcl_name;
+       char                    *vcl_name;
+
+       TAILQ_ENTRY(backend)    list;
+       int                     refcount;
 
        struct backend_method   *method;
 
-       const char              *hostname;
-       const char              *portname;
+       char                    *hostname;
+       char                    *portname;
 
        struct addrinfo         *addr;
        struct addrinfo         *last_addr;
@@ -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 ----------------------------------------------------*/
 
 
@@ -393,6 +402,9 @@ void VBE_ClosedFd(struct worker *w, struct vbe_conn *vc);
 void VBE_RecycleFd(struct worker *w, struct vbe_conn *vc);
 struct bereq * VBE_new_bereq(void);
 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 */
 extern struct backend_method   backend_method_simple;
index 1170d4816bc0b9d5531d337b9e6a1f91999c72da..1d1bad190daa9057e7fcc2f0e03e1d07f09c7846 100644 (file)
@@ -41,7 +41,9 @@
 
 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.
@@ -53,11 +55,11 @@ VBE_new_bereq(void)
        struct bereq *bereq;
        volatile unsigned len;
 
-       LOCK(&vbemtx);
+       LOCK(&VBE_mtx);
        bereq = TAILQ_FIRST(&bereq_head);
        if (bereq != NULL)
                TAILQ_REMOVE(&bereq_head, bereq, list);
-       UNLOCK(&vbemtx);
+       UNLOCK(&VBE_mtx);
        if (bereq != NULL) {
                CHECK_OBJ(bereq, BEREQ_MAGIC);
        } else {
@@ -81,9 +83,44 @@ VBE_free_bereq(struct bereq *bereq)
 {
 
        CHECK_OBJ_NOTNULL(bereq, BEREQ_MAGIC);
-       LOCK(&vbemtx);
+       LOCK(&VBE_mtx);
        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
 VBE_Init(void)
 {
 
-       MTX_INIT(&vbemtx);
+       MTX_INIT(&VBE_mtx);
        backend_method_simple.init();
 }
index b6876422d6b344f975e161e7f37c816d5acf3f3e..6ccfaacdbf6dd2ee5d3929dcbccbd6b4c3947a14 100644 (file)
@@ -520,11 +520,27 @@ VRT_init_simple_backend(struct backend **bp, struct vrt_simple_backend *t)
 {
        struct backend *b;
        
-       b = calloc(sizeof *b, 1);
-       XXXAN(b);
-       b->magic = BACKEND_MAGIC;
+       /*
+        * Scan existing backends to see if we can recycle one of them.
+        */
+       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;
-       TAILQ_INIT(&b->connlist);
        b->last_check = TIM_mono();
        b->minute_limit = 1;
 
@@ -540,13 +556,12 @@ VRT_init_simple_backend(struct backend **bp, struct vrt_simple_backend *t)
        b->hostname = strdup(t->host);
        XXXAN(b->hostname);
 
-       b->method = &backend_method_simple;
-
        *bp = b;
 }
 
 void
 VRT_fini_backend(struct backend *b)
 {
-       (void)b;
+
+       VBE_DropRef(b); 
 }