From: phk Date: Fri, 20 Feb 2009 11:05:14 +0000 (+0000) Subject: Be more defensive around objhead retirement. X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c249a21f2807ab3b32447d540ede86132f6a8997;p=varnish Be more defensive around objhead retirement. git-svn-id: svn+ssh://projects.linpro.no/svn/varnish/trunk@3791 d4fa192b-c00b-0410-8231-f00ffab90ce4 --- diff --git a/varnish-cache/bin/varnishd/cache_ban.c b/varnish-cache/bin/varnishd/cache_ban.c index eb5ee7b6..a7fb7944 100644 --- a/varnish-cache/bin/varnishd/cache_ban.c +++ b/varnish-cache/bin/varnishd/cache_ban.c @@ -469,6 +469,7 @@ BAN_DestroyObj(struct object *o) return; CHECK_OBJ_NOTNULL(o->ban, BAN_MAGIC); Lck_Lock(&ban_mtx); + assert(o->ban->refcount > 0); o->ban->refcount--; o->ban = NULL; @@ -477,7 +478,6 @@ BAN_DestroyObj(struct object *o) Lck_Unlock(&ban_mtx); if (b != NULL) BAN_Free(b); - } diff --git a/varnish-cache/bin/varnishd/cache_expire.c b/varnish-cache/bin/varnishd/cache_expire.c index 581bfb33..b96c831c 100644 --- a/varnish-cache/bin/varnishd/cache_expire.c +++ b/varnish-cache/bin/varnishd/cache_expire.c @@ -272,6 +272,7 @@ exp_timer(void *arg) "%u %d", o->xid, (int)(o->ttl - t)); Lck_Lock(&exp_mtx); assert(oc->timer_idx == BINHEAP_NOIDX); + assert(oc->flags & OC_F_ONLRU); VTAILQ_REMOVE(&lru, o->objcore, lru_list); oc->flags &= ~OC_F_ONLRU; VSL_stats->n_expired++; diff --git a/varnish-cache/bin/varnishd/cache_hash.c b/varnish-cache/bin/varnishd/cache_hash.c index 554b8b79..3b704fe4 100644 --- a/varnish-cache/bin/varnishd/cache_hash.c +++ b/varnish-cache/bin/varnishd/cache_hash.c @@ -140,6 +140,18 @@ HSH_Prealloc(struct sess *sp) CHECK_OBJ_NOTNULL(w->nobj, OBJECT_MAGIC); } +void +HSH_DeleteObjHead(struct objhead *oh) +{ + + AZ(oh->refcnt); + assert(VTAILQ_EMPTY(&oh->objcs)); + Lck_Delete(&oh->mtx); + VSL_stats->n_objecthead--; + free(oh->hash); + FREE_OBJ(oh); +} + void HSH_Freestore(struct object *o) { @@ -311,7 +323,7 @@ HSH_Lookup(struct sess *sp) if (o->hits < INT_MAX) o->hits++; Lck_Unlock(&oh->mtx); - (void)hash->deref(oh); + assert(hash->deref(oh)); return (o); } @@ -476,6 +488,7 @@ HSH_Deref(struct object **oo) return; BAN_DestroyObj(o); + AZ(o->ban); DSL(0x40, SLT_Debug, 0, "Object %u workspace min free %u", o->xid, WS_Free(o->ws_o)); @@ -494,13 +507,10 @@ HSH_Deref(struct object **oo) AN(oc); FREE_OBJ(oc); /* Drop our ref on the objhead */ + assert(oh->refcnt > 0); if (hash->deref(oh)) return; - assert(VTAILQ_EMPTY(&oh->objcs)); - Lck_Delete(&oh->mtx); - VSL_stats->n_objecthead--; - free(oh->hash); - FREE_OBJ(oh); + HSH_DeleteObjHead(oh); } void diff --git a/varnish-cache/bin/varnishd/hash_critbit.c b/varnish-cache/bin/varnishd/hash_critbit.c index d43a78ec..35713201 100644 --- a/varnish-cache/bin/varnishd/hash_critbit.c +++ b/varnish-cache/bin/varnishd/hash_critbit.c @@ -323,7 +323,7 @@ dump(const struct hcb_root *root, FILE *fd) /**********************************************************************/ -#define COOL_DURATION 15 /* seconds */ +#define COOL_DURATION 60 /* seconds */ static void * hcb_cleaner(void *priv) @@ -337,10 +337,6 @@ hcb_cleaner(void *priv) (void)sleep(1); Lck_Lock(&hcb_mtx); VTAILQ_FOREACH_SAFE(oh, &laylow, coollist, oh2) { - if (oh->hash != NULL) { - free(oh->hash); - oh->hash = NULL; - } y = (void *)&oh->u; if (y->leaf[0] || y->leaf[1]) continue; @@ -349,8 +345,8 @@ hcb_cleaner(void *priv) #ifdef PHK fprintf(stderr, "OH %p is cold enough\n", oh); #endif - free(oh); - VSL_stats->n_objecthead--; + oh->refcnt = 0; + HSH_DeleteObjHead(oh); } } Lck_Unlock(&hcb_mtx); @@ -381,6 +377,7 @@ hcb_deref(struct objhead *oh) r = 1; CHECK_OBJ_NOTNULL(oh, OBJHEAD_MAGIC); Lck_Lock(&oh->mtx); + assert(oh->refcnt > 0); if (--oh->refcnt == 0) { Lck_Lock(&hcb_mtx); hcb_delete(&hcb_root, oh); diff --git a/varnish-cache/bin/varnishd/hash_slinger.h b/varnish-cache/bin/varnishd/hash_slinger.h index bb53e246..3e96e74f 100644 --- a/varnish-cache/bin/varnishd/hash_slinger.h +++ b/varnish-cache/bin/varnishd/hash_slinger.h @@ -50,6 +50,7 @@ struct hash_slinger { /* cache_hash.c */ void HSH_Prealloc(struct sess *sp); +void HSH_DeleteObjHead(struct objhead *oh); void HSH_Freestore(struct object *o); void HSH_Copy(const struct sess *sp, struct objhead *o); struct object *HSH_Lookup(struct sess *sp);