r3845 - trunk/varnish-cache/bin/varnishd
phk at projects.linpro.no
phk at projects.linpro.no
Sat Feb 28 22:56:49 CET 2009
Author: phk
Date: 2009-02-28 22:56:49 +0100 (Sat, 28 Feb 2009)
New Revision: 3845
Modified:
trunk/varnish-cache/bin/varnishd/cache.h
trunk/varnish-cache/bin/varnishd/cache_center.c
trunk/varnish-cache/bin/varnishd/cache_fetch.c
trunk/varnish-cache/bin/varnishd/cache_hash.c
trunk/varnish-cache/bin/varnishd/hash_slinger.h
Log:
Postpone allocating the actual object until we have received the
headers and vcl_fetch{} has told os what to do with it.
Modified: trunk/varnish-cache/bin/varnishd/cache.h
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache.h 2009-02-28 21:21:14 UTC (rev 3844)
+++ trunk/varnish-cache/bin/varnishd/cache.h 2009-02-28 21:56:49 UTC (rev 3845)
@@ -396,6 +396,7 @@
struct vbe_conn *vbe;
struct bereq *bereq;
struct object *obj;
+ struct objcore *objcore;
struct objhead *objhead;
struct VCL_conf *vcl;
Modified: trunk/varnish-cache/bin/varnishd/cache_center.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache_center.c 2009-02-28 21:21:14 UTC (rev 3844)
+++ trunk/varnish-cache/bin/varnishd/cache_center.c 2009-02-28 21:56:49 UTC (rev 3845)
@@ -378,6 +378,7 @@
{
int i;
struct http *hp, *hp2;
+ struct object *o;
char *b;
CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
@@ -387,9 +388,6 @@
AN(sp->director);
AZ(sp->vbe);
- sp->obj->xid = sp->xid;
- WS_Assert(sp->obj->ws_o);
-
i = FetchHdr(sp);
/*
@@ -402,7 +400,11 @@
sp->err_code = 503;
sp->step = STP_ERROR;
VBE_free_bereq(&sp->bereq);
- HSH_Drop(sp);
+ if (sp->objhead) {
+ CHECK_OBJ_NOTNULL(sp->objhead, OBJHEAD_MAGIC);
+ CHECK_OBJ_NOTNULL(sp->objcore, OBJCORE_MAGIC);
+ HSH_DerefObjCore(sp);
+ }
AZ(sp->obj);
return (0);
}
@@ -440,6 +442,21 @@
VCL_fetch_method(sp);
+ o = HSH_NewObject(sp, sp->handling != VCL_RET_DELIVER);
+
+ if (sp->objhead != NULL) {
+ CHECK_OBJ_NOTNULL(sp->objhead, OBJHEAD_MAGIC);
+ CHECK_OBJ_NOTNULL(sp->objcore, OBJCORE_MAGIC);
+ sp->objcore->obj = o;
+ o->objcore = sp->objcore;
+ o->objhead = sp->objhead;
+ sp->objhead = NULL; /* refcnt follows pointer. */
+ }
+ sp->obj = o;
+
+ BAN_NewObj(sp->obj);
+
+ sp->obj->xid = sp->xid;
sp->obj->response = sp->err_code;
sp->obj->cacheable = sp->bereq->cacheable;
sp->obj->ttl = sp->bereq->ttl;
@@ -448,6 +465,7 @@
sp->obj->cacheable = 0;
sp->obj->age = sp->bereq->age;
sp->obj->entered = sp->bereq->entered;
+ WS_Assert(sp->obj->ws_o);
/* Filter into object */
hp = sp->bereq->beresp;
@@ -602,6 +620,9 @@
/* Drop our object, we won't need it */
HSH_Deref(sp->wrk, &sp->obj);
+ sp->objcore = NULL;
+ AZ(sp->objhead);
+ sp->objhead = NULL;
switch(sp->handling) {
case VCL_RET_PASS:
@@ -675,6 +696,7 @@
return (1);
}
+ CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC);
CHECK_OBJ_NOTNULL(oh, OBJHEAD_MAGIC);
/* If we inserted a new object it's a miss */
@@ -682,14 +704,8 @@
VSL_stats->cache_miss++;
AZ(oc->obj);
- o = HSH_NewObject(sp, 0);
-
- o->objhead = oh;
- o->objcore = oc;
- oc->obj = o;
- sp->obj = o;
-
- BAN_NewObj(o);
+ sp->objhead = oh;
+ sp->objcore = oc;
sp->step = STP_MISS;
return (0);
}
@@ -702,6 +718,8 @@
VSL_stats->cache_hitpass++;
WSP(sp, SLT_HitPass, "%u", sp->obj->xid);
HSH_Deref(sp->wrk, &sp->obj);
+ sp->objcore = NULL;
+ sp->objhead = NULL;
sp->step = STP_PASS;
return (0);
}
@@ -740,27 +758,29 @@
{
CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
- CHECK_OBJ_NOTNULL(sp->obj, OBJECT_MAGIC);
CHECK_OBJ_NOTNULL(sp->vcl, VCL_CONF_MAGIC);
+ AZ(sp->obj);
+ AN(sp->objcore);
+ AN(sp->objhead);
http_FilterHeader(sp, HTTPH_R_FETCH);
VCL_miss_method(sp);
- AZ(sp->obj->cacheable);
switch(sp->handling) {
case VCL_RET_ERROR:
- HSH_Drop(sp);
+ HSH_DerefObjCore(sp);
VBE_free_bereq(&sp->bereq);
sp->step = STP_ERROR;
return (0);
case VCL_RET_PASS:
- HSH_Drop(sp);
VBE_free_bereq(&sp->bereq);
+ HSH_DerefObjCore(sp);
sp->step = STP_PASS;
return (0);
case VCL_RET_FETCH:
sp->step = STP_FETCH;
return (0);
case VCL_RET_RESTART:
+ HSH_DerefObjCore(sp);
VBE_free_bereq(&sp->bereq);
INCOMPL();
default:
@@ -818,8 +838,6 @@
}
assert(sp->handling == VCL_RET_PASS);
sp->acct_req.pass++;
- HSH_Prealloc(sp);
- sp->obj = HSH_NewObject(sp, 1);
sp->sendbody = 1;
sp->step = STP_FETCH;
return (0);
Modified: trunk/varnish-cache/bin/varnishd/cache_fetch.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache_fetch.c 2009-02-28 21:21:14 UTC (rev 3844)
+++ trunk/varnish-cache/bin/varnishd/cache_fetch.c 2009-02-28 21:56:49 UTC (rev 3845)
@@ -319,11 +319,14 @@
CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
CHECK_OBJ_NOTNULL(sp->wrk, WORKER_MAGIC);
- CHECK_OBJ_NOTNULL(sp->obj, OBJECT_MAGIC);
CHECK_OBJ_NOTNULL(sp->bereq, BEREQ_MAGIC);
AN(sp->director);
- if (sp->obj->objcore != NULL) /* pass has no objcore */
- AN(ObjIsBusy(sp->obj));
+ AZ(sp->obj);
+ if (sp->objcore != NULL) { /* pass has no objcore */
+ CHECK_OBJ_NOTNULL(sp->objcore, OBJCORE_MAGIC);
+ AN(sp->objhead); /* details in hash_slinger.h */
+ AN(sp->objcore->flags & OC_F_BUSY);
+ }
AN(sp->bereq);
/* Transmit request */
Modified: trunk/varnish-cache/bin/varnishd/cache_hash.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache_hash.c 2009-02-28 21:21:14 UTC (rev 3844)
+++ trunk/varnish-cache/bin/varnishd/cache_hash.c 2009-02-28 21:56:49 UTC (rev 3845)
@@ -308,6 +308,8 @@
busy_oc = NULL;
grace_oc = NULL;
VTAILQ_FOREACH(oc, &oh->objcs, list) {
+ /* Must be at least our own ref + the objcore we examine */
+ assert(oh->refcnt > 1);
CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC);
if (oc->flags & OC_F_BUSY) {
@@ -359,6 +361,7 @@
o->refcnt++;
if (o->hits < INT_MAX)
o->hits++;
+ assert(oh->refcnt > 1);
Lck_Unlock(&oh->mtx);
assert(hash->deref(oh));
*poh = oh;
@@ -454,10 +457,10 @@
Lck_Lock(&oh->mtx);
}
o->objcore->flags &= ~OC_F_BUSY;
- if (oh != NULL)
+ if (oh != NULL) {
hsh_rush(oh);
- if (oh != NULL)
Lck_Unlock(&oh->mtx);
+ }
}
void
@@ -475,6 +478,29 @@
}
void
+HSH_DerefObjCore(struct sess *sp)
+{
+ struct objhead *oh;
+ struct objcore *oc;
+
+ CHECK_OBJ_NOTNULL(sp->objhead, OBJHEAD_MAGIC);
+ CHECK_OBJ_NOTNULL(sp->objcore, OBJCORE_MAGIC);
+
+ oh = sp->objhead;
+ sp->objhead = NULL;
+ oc = sp->objcore;
+ sp->objcore = NULL;
+
+ Lck_Lock(&oh->mtx);
+ VTAILQ_REMOVE(&oh->objcs, oc, list);
+ Lck_Unlock(&oh->mtx);
+ assert(oh->refcnt > 0);
+ if (hash->deref(oh))
+ return;
+ HSH_DeleteObjHead(sp->wrk, oh);
+}
+
+void
HSH_Deref(const struct worker *w, struct object **oo)
{
struct object *o;
@@ -492,7 +518,7 @@
assert(o->refcnt > 0);
r = --o->refcnt;
} else {
- CHECK_OBJ(oh, OBJHEAD_MAGIC);
+ CHECK_OBJ_NOTNULL(oh, OBJHEAD_MAGIC);
oc = o->objcore;
CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC);
@@ -525,6 +551,7 @@
STV_free(o->objstore);
else
FREE_OBJ(o);
+ o = NULL;
w->stats->n_object--;
if (oh == NULL) {
@@ -540,6 +567,7 @@
HSH_DeleteObjHead(w, oh);
}
+
void
HSH_Init(void)
{
Modified: trunk/varnish-cache/bin/varnishd/hash_slinger.h
===================================================================
--- trunk/varnish-cache/bin/varnishd/hash_slinger.h 2009-02-28 21:21:14 UTC (rev 3844)
+++ trunk/varnish-cache/bin/varnishd/hash_slinger.h 2009-02-28 21:56:49 UTC (rev 3845)
@@ -63,6 +63,7 @@
void HSH_Init(void);
void HSH_AddString(struct sess *sp, const char *str);
void HSH_Prepare(struct sess *sp, unsigned hashcount);
+void HSH_DerefObjCore(struct sess *sp);
#ifdef VARNISH_CACHE_CHILD
More information about the varnish-commit
mailing list