[PATCH] Expire callback implementation

Martin Blix Grydeland martin at varnish-software.com
Fri Jun 14 14:19:38 CEST 2013


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




More information about the varnish-dev mailing list