]> err.no Git - varnish/commitdiff
With Vary, Prefetch and degraded mode, a session sleeps not on a
authorphk <phk@d4fa192b-c00b-0410-8231-f00ffab90ce4>
Mon, 28 Jan 2008 09:01:38 +0000 (09:01 +0000)
committerphk <phk@d4fa192b-c00b-0410-8231-f00ffab90ce4>
Mon, 28 Jan 2008 09:01:38 +0000 (09:01 +0000)
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
varnish-cache/bin/varnishd/cache_center.c
varnish-cache/bin/varnishd/cache_hash.c

index a10d75bf5f0370dbc1c7f59ed4cb377207826ae7..594b3e7bb33fb6e73f3df63e1560123c792b266a 100644 (file)
@@ -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 */
index dcb0a5f85e4ae04e63d59024b2483296fdef1bca..beab91888ef07fe7053d116d96fcfca5c840bc15 100644 (file)
@@ -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
index 9135712759dca46415d94c18d5e6982a680cd649..df3fc0078f7630a592be6a6c41729f698d2b5c96 100644 (file)
@@ -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);