From d604caeaf64bbecfff49d4686dfdd86659ff9986 Mon Sep 17 00:00:00 2001 From: phk Date: Mon, 28 Jan 2008 09:01:38 +0000 Subject: [PATCH] With Vary, Prefetch and degraded mode, a session sleeps not on a particular object, because we cannot know beforehand if it will work out for us, but sleeps on any one of potentially multiple busy objects becoming ready for us to test against. Therefore it makes sense to move the waiting list from the object to the object head, as this both simplifies the code and eliminates a refhold on busy objects. git-svn-id: svn+ssh://projects.linpro.no/svn/varnish/trunk@2389 d4fa192b-c00b-0410-8231-f00ffab90ce4 --- varnish-cache/bin/varnishd/cache.h | 4 ++-- varnish-cache/bin/varnishd/cache_center.c | 2 +- varnish-cache/bin/varnishd/cache_hash.c | 25 +++++++++++------------ 3 files changed, 15 insertions(+), 16 deletions(-) diff --git a/varnish-cache/bin/varnishd/cache.h b/varnish-cache/bin/varnishd/cache.h index a10d75bf..594b3e7b 100644 --- a/varnish-cache/bin/varnishd/cache.h +++ b/varnish-cache/bin/varnishd/cache.h @@ -267,8 +267,6 @@ struct object { VTAILQ_HEAD(, storage) store; - VTAILQ_HEAD(, sess) waitinglist; - VTAILQ_HEAD(, esi_bit) esibits; double lru_stamp; @@ -283,6 +281,7 @@ struct objhead { VTAILQ_HEAD(,object) objects; char *hash; unsigned hashlen; + VTAILQ_HEAD(, sess) waitinglist; }; /* -------------------------------------------------------------------*/ @@ -339,6 +338,7 @@ struct sess { struct backend *backend; struct bereq *bereq; struct object *obj; + struct objhead *objhead; struct VCL_conf *vcl; /* Various internal stuff */ diff --git a/varnish-cache/bin/varnishd/cache_center.c b/varnish-cache/bin/varnishd/cache_center.c index dcb0a5f8..beab9188 100644 --- a/varnish-cache/bin/varnishd/cache_center.c +++ b/varnish-cache/bin/varnishd/cache_center.c @@ -541,7 +541,7 @@ cnt_lookup(struct sess *sp) * We hit a busy object, disembark worker thread and expect * hash code to restart us, still in STP_LOOKUP, later. */ - WSP(sp, SLT_Debug, "on waiting list on obj %u", sp->obj->xid); + WSP(sp, SLT_Debug, "on waiting list <%s>", sp->objhead->hash); /* * There is a non-zero risk that we come here more than once * before we get through, in that case cnt_recv must be set diff --git a/varnish-cache/bin/varnishd/cache_hash.c b/varnish-cache/bin/varnishd/cache_hash.c index 91357127..df3fc007 100644 --- a/varnish-cache/bin/varnishd/cache_hash.c +++ b/varnish-cache/bin/varnishd/cache_hash.c @@ -81,6 +81,7 @@ HSH_Prealloc(struct sess *sp) XXXAN(w->nobjhead); w->nobjhead->magic = OBJHEAD_MAGIC; VTAILQ_INIT(&w->nobjhead->objects); + VTAILQ_INIT(&w->nobjhead->waitinglist); MTX_INIT(&w->nobjhead->mtx); VSL_stats->n_objecthead++; } else @@ -98,7 +99,6 @@ HSH_Prealloc(struct sess *sp) w->nobj->busy = 1; w->nobj->refcnt = 1; VTAILQ_INIT(&w->nobj->store); - VTAILQ_INIT(&w->nobj->waitinglist); VTAILQ_INIT(&w->nobj->esibits); VSL_stats->n_object++; } else @@ -183,10 +183,10 @@ HSH_Lookup(struct sess *sp) h = sp->http; HSH_Prealloc(sp); - if (sp->obj != NULL) { - CHECK_OBJ_NOTNULL(sp->obj, OBJECT_MAGIC); - oh = sp->obj->objhead; - HSH_Deref(sp->obj); + if (sp->objhead != NULL) { + CHECK_OBJ_NOTNULL(sp->objhead, OBJHEAD_MAGIC); + oh = sp->objhead; + sp->objhead = NULL; CHECK_OBJ_NOTNULL(oh, OBJHEAD_MAGIC); LOCK(&oh->mtx); } else { @@ -199,9 +199,8 @@ HSH_Lookup(struct sess *sp) VTAILQ_FOREACH(o, &oh->objects, list) { if (o->busy) { - VTAILQ_INSERT_TAIL(&o->waitinglist, sp, list); - sp->obj = o; - o->refcnt++; + VTAILQ_INSERT_TAIL(&oh->waitinglist, sp, list); + sp->objhead = oh; UNLOCK(&oh->mtx); return (NULL); } @@ -245,16 +244,16 @@ HSH_Lookup(struct sess *sp) } static void -hsh_rush(struct object *o) +hsh_rush(struct objhead *oh) { unsigned u; struct sess *sp; for (u = 0; u < params->rush_exponent; u++) { - sp = VTAILQ_FIRST(&o->waitinglist); + sp = VTAILQ_FIRST(&oh->waitinglist); if (sp == NULL) return; - VTAILQ_REMOVE(&o->waitinglist, sp, list); + VTAILQ_REMOVE(&oh->waitinglist, sp, list); VSL(SLT_Debug, sp->id, "of waiting list"); WRK_QueueSession(sp); } @@ -276,7 +275,7 @@ HSH_Unbusy(struct object *o) LOCK(&oh->mtx); } o->busy = 0; - hsh_rush(o); + hsh_rush(oh); if (oh != NULL) UNLOCK(&oh->mtx); } @@ -314,7 +313,7 @@ HSH_Deref(struct object *o) } assert(o->refcnt > 0); r = --o->refcnt; - hsh_rush(o); + hsh_rush(oh); if (oh != NULL) { if (!r) VTAILQ_REMOVE(&oh->objects, o, list); -- 2.39.5