From d7c7e49b5f785a73c4fe353b6c45a6965739b68c Mon Sep 17 00:00:00 2001 From: phk Date: Tue, 21 Aug 2007 18:57:14 +0000 Subject: [PATCH] Move the connection (data structure pool) into the generic backend handling. Add more asserts. git-svn-id: svn+ssh://projects.linpro.no/svn/varnish/trunk@1918 d4fa192b-c00b-0410-8231-f00ffab90ce4 --- varnish-cache/bin/varnishd/cache.h | 4 + varnish-cache/bin/varnishd/cache_backend.c | 93 ++++++++++++++++++++-- 2 files changed, 91 insertions(+), 6 deletions(-) diff --git a/varnish-cache/bin/varnishd/cache.h b/varnish-cache/bin/varnishd/cache.h index 21c74f01..08e79896 100644 --- a/varnish-cache/bin/varnishd/cache.h +++ b/varnish-cache/bin/varnishd/cache.h @@ -355,6 +355,7 @@ struct backend { TAILQ_ENTRY(backend) list; int refcount; + pthread_mutex_t mtx; struct backend_method *method; void *priv; @@ -390,7 +391,10 @@ struct bereq * VBE_new_bereq(void); void VBE_free_bereq(struct bereq *bereq); extern struct backendlist backendlist; void VBE_DropRef(struct backend *); +void VBE_DropRefLocked(struct backend *); struct backend *VBE_NewBackend(struct backend_method *method); +struct vbe_conn *VBE_NewConn(void); +void VBE_ReleaseConn(struct vbe_conn *); /* cache_backend_simple.c */ extern struct backend_method backend_method_simple; diff --git a/varnish-cache/bin/varnishd/cache_backend.c b/varnish-cache/bin/varnishd/cache_backend.c index 8d392c16..b810fab0 100644 --- a/varnish-cache/bin/varnishd/cache_backend.c +++ b/varnish-cache/bin/varnishd/cache_backend.c @@ -40,6 +40,7 @@ #include "cache.h" static TAILQ_HEAD(,bereq) bereq_head = TAILQ_HEAD_INITIALIZER(bereq_head); +static TAILQ_HEAD(,vbe_conn) vbe_head = TAILQ_HEAD_INITIALIZER(vbe_head); static MTX VBE_mtx; @@ -90,6 +91,50 @@ VBE_free_bereq(struct bereq *bereq) /*--------------------------------------------------------------------*/ +struct vbe_conn * +VBE_NewConn(void) +{ + struct vbe_conn *vc; + + vc = TAILQ_FIRST(&vbe_head); + if (vc != NULL) { + LOCK(&VBE_mtx); + vc = TAILQ_FIRST(&vbe_head); + if (vc != NULL) { + VSL_stats->backend_unused--; + TAILQ_REMOVE(&vbe_head, vc, list); + } else { + VSL_stats->n_vbe_conn++; + } + UNLOCK(&VBE_mtx); + } + if (vc != NULL) + return (vc); + + vc = calloc(sizeof *vc, 1); + XXXAN(vc); + vc->magic = VBE_CONN_MAGIC; + vc->fd = -1; + return (vc); +} + +/*--------------------------------------------------------------------*/ + +void +VBE_ReleaseConn(struct vbe_conn *vc) +{ + + CHECK_OBJ_NOTNULL(vc, VBE_CONN_MAGIC); + assert(vc->backend == NULL); + assert(vc->fd < 0); + LOCK(&VBE_mtx); + TAILQ_INSERT_HEAD(&vbe_head, vc, list); + VSL_stats->backend_unused++; + UNLOCK(&VBE_mtx); +} + +/*--------------------------------------------------------------------*/ + struct backend * VBE_NewBackend(struct backend_method *method) { @@ -99,9 +144,13 @@ VBE_NewBackend(struct backend_method *method) XXXAN(b); b->magic = BACKEND_MAGIC; b->method = method; + + MTX_INIT(&b->mtx); b->refcount = 1; + b->last_check = TIM_mono(); b->minute_limit = 1; + TAILQ_INSERT_TAIL(&backendlist, b, list); return (b); } @@ -109,26 +158,44 @@ VBE_NewBackend(struct backend_method *method) /*--------------------------------------------------------------------*/ void -VBE_DropRef(struct backend *b) +VBE_DropRefLocked(struct backend *b) { + int i; CHECK_OBJ_NOTNULL(b, BACKEND_MAGIC); - b->refcount--; - if (b->refcount > 0) + i = --b->refcount; + if (i == 0) + TAILQ_REMOVE(&backendlist, b, list); + UNLOCK(&b->mtx); + if (i) return; - TAILQ_REMOVE(&backendlist, b, list); + b->magic = 0; b->method->cleanup(b); free(b->vcl_name); free(b); } +void +VBE_DropRef(struct backend *b) +{ + + CHECK_OBJ_NOTNULL(b, BACKEND_MAGIC); + + LOCK(&b->mtx); + VBE_DropRefLocked(b); +} + /*--------------------------------------------------------------------*/ struct vbe_conn * VBE_GetFd(struct sess *sp) { + CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); + CHECK_OBJ_NOTNULL(sp->backend, BACKEND_MAGIC); + AN(sp->backend->method); + AN(sp->backend->method->getfd); return(sp->backend->method->getfd(sp)); } @@ -137,8 +204,15 @@ VBE_GetFd(struct sess *sp) void VBE_ClosedFd(struct worker *w, struct vbe_conn *vc) { + struct backend *b; - vc->backend->method->close(w, vc); + CHECK_OBJ_NOTNULL(vc, VBE_CONN_MAGIC); + CHECK_OBJ_NOTNULL(vc->backend, BACKEND_MAGIC); + b = vc->backend; + AN(b->method); + AN(b->method->close); + b->method->close(w, vc); + CHECK_OBJ_NOTNULL(b, BACKEND_MAGIC); } /* Recycle a connection ----------------------------------------------*/ @@ -146,8 +220,15 @@ VBE_ClosedFd(struct worker *w, struct vbe_conn *vc) void VBE_RecycleFd(struct worker *w, struct vbe_conn *vc) { + struct backend *b; - vc->backend->method->recycle(w, vc); + CHECK_OBJ_NOTNULL(vc, VBE_CONN_MAGIC); + CHECK_OBJ_NOTNULL(vc->backend, BACKEND_MAGIC); + b = vc->backend; + AN(b->method); + AN(b->method->recycle); + b->method->recycle(w, vc); + CHECK_OBJ_NOTNULL(b, BACKEND_MAGIC); } /*--------------------------------------------------------------------*/ -- 2.39.5