
martin at varnish-software
Jun 14, 2013, 5:19 AM
Post #1 of 1
(76 views)
Permalink
|
|
[PATCH] Expire callback implementation
|
|
This allows a vmod to have knowledge of all objects present in the cache at any time. (Use case: secondary hashes) --- bin/varnishd/cache/cache.h | 12 +++++++ bin/varnishd/cache/cache_expire.c | 70 +++++++++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+) diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h index 77ef0d5..b7937eb 100644 --- a/bin/varnishd/cache/cache.h +++ b/bin/varnishd/cache/cache.h @@ -278,6 +278,16 @@ struct exp { double entered; }; +typedef void exp_callback_f(struct objcore *oc, void *priv); +struct exp_callback { + unsigned magic; +#define EXP_CALLBACK_MAGIC 0xAB956EB1 + exp_callback_f *cb_insert; + exp_callback_f *cb_remove; + void *priv; + VTAILQ_ENTRY(exp_callback) list; +}; + /*--------------------------------------------------------------------*/ struct vsl_log { @@ -812,6 +822,8 @@ void EXP_Rearm(const struct object *o); int EXP_Touch(struct objcore *oc); int EXP_NukeOne(struct busyobj *, struct lru *lru); void EXP_NukeLRU(struct worker *wrk, struct vsl_log *vsl, struct lru *lru); +void EXP_Reg_Callback(struct exp_callback *cb); +void EXP_Dereg_Callback(struct exp_callback *cb); /* cache_fetch.c */ void VBF_Fetch(struct worker *wrk, struct req *req); diff --git a/bin/varnishd/cache/cache_expire.c b/bin/varnishd/cache/cache_expire.c index 2271949..e1fff36 100644 --- a/bin/varnishd/cache/cache_expire.c +++ b/bin/varnishd/cache/cache_expire.c @@ -63,6 +63,43 @@ static pthread_t exp_thread; static struct binheap *exp_heap; static struct lock exp_mtx; +static VTAILQ_HEAD(,exp_callback) exp_cb_list; +static pthread_rwlock_t exp_cb_mtx; + +static void +exp_insert_cb(struct objcore *oc) +{ + struct exp_callback *cb; + + if (VTAILQ_EMPTY(&exp_cb_list)) + return; + + AZ(pthread_rwlock_rdlock(&exp_cb_mtx)); + VTAILQ_FOREACH(cb, &exp_cb_list, list) { + CHECK_OBJ_NOTNULL(cb, EXP_CALLBACK_MAGIC); + if (cb->cb_insert) + cb->cb_insert(oc, cb->priv); + } + AZ(pthread_rwlock_unlock(&exp_cb_mtx)); +} + +static void +exp_remove_cb(struct objcore *oc) +{ + struct exp_callback *cb; + + if (VTAILQ_EMPTY(&exp_cb_list)) + return; + + AZ(pthread_rwlock_rdlock(&exp_cb_mtx)); + VTAILQ_FOREACH(cb, &exp_cb_list, list) { + CHECK_OBJ_NOTNULL(cb, EXP_CALLBACK_MAGIC); + if (cb->cb_remove) + cb->cb_remove(oc, cb->priv); + } + AZ(pthread_rwlock_unlock(&exp_cb_mtx)); +} + /*-------------------------------------------------------------------- * struct exp manipulations * @@ -226,6 +263,8 @@ EXP_Insert(struct object *o) CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC); HSH_Ref(oc); + exp_insert_cb(oc); + assert(o->exp.entered != 0 && !isnan(o->exp.entered)); o->last_lru = o->exp.entered; @@ -411,6 +450,7 @@ exp_timer(struct worker *wrk, void *priv) VSLb(&vsl, SLT_ExpKill, "%u %.0f", oc_getxid(&wrk->stats, oc) & VSL_IDENTMASK, EXP_Ttl(NULL, o) - t); + exp_remove_cb(oc); (void)HSH_Deref(&wrk->stats, oc, NULL); } NEEDLESS_RETURN(NULL); @@ -457,10 +497,38 @@ EXP_NukeOne(struct busyobj *bo, struct lru *lru) /* XXX: bad idea for -spersistent */ VSLb(bo->vsl, SLT_ExpKill, "%u LRU", oc_getxid(bo->stats, oc) & VSL_IDENTMASK); + exp_remove_cb(oc); (void)HSH_Deref(bo->stats, oc, NULL); return (1); } +void +EXP_Reg_Callback(struct exp_callback *cb) +{ + CHECK_OBJ_NOTNULL(cb, EXP_CALLBACK_MAGIC); + AZ(pthread_rwlock_wrlock(&exp_cb_mtx)); + VTAILQ_INSERT_TAIL(&exp_cb_list, cb, list); + AZ(pthread_rwlock_unlock(&exp_cb_mtx)); +} + +void +EXP_Dereg_Callback(struct exp_callback *cb) +{ + struct exp_callback *cb2; + + CHECK_OBJ_NOTNULL(cb, EXP_CALLBACK_MAGIC); + AZ(pthread_rwlock_wrlock(&exp_cb_mtx)); + VTAILQ_FOREACH(cb2, &exp_cb_list, list) { + CHECK_OBJ_NOTNULL(cb, EXP_CALLBACK_MAGIC); + if (cb2 == cb) { + VTAILQ_REMOVE(&exp_cb_list, cb2, list); + break; + } + } + AN(cb2); + AZ(pthread_rwlock_unlock(&exp_cb_mtx)); +} + /*-------------------------------------------------------------------- * Nukes an entire LRU */ @@ -555,6 +623,8 @@ EXP_Init(void) { Lck_New(&exp_mtx, lck_exp); + AZ(pthread_rwlock_init(&exp_cb_mtx, NULL)); + VTAILQ_INIT(&exp_cb_list); exp_heap = binheap_new(NULL, object_cmp, object_update); XXXAN(exp_heap); WRK_BgThread(&exp_thread, "cache-timeout", exp_timer, NULL); -- 1.7.10.4 _______________________________________________ varnish-dev mailing list varnish-dev [at] varnish-cache https://www.varnish-cache.org/lists/mailman/listinfo/varnish-dev
|