---
 bin/varnishd/cache/cache.h                     | 18 +++++-
 bin/varnishd/cache/cache_expire.c              | 77 +++++++++++++++++++++++++-
 bin/varnishd/cache/cache_hash.c                |  2 +-
 bin/varnishd/storage/storage_persistent_silo.c |  2 +-
 4 files changed, 93 insertions(+), 6 deletions(-)

diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h
index faaaf4f..6c17c52 100644
--- a/bin/varnishd/cache/cache.h
+++ b/bin/varnishd/cache/cache.h
@@ -288,6 +288,18 @@ struct exp {
 
 /*--------------------------------------------------------------------*/
 
+typedef void exp_callback_f(struct worker *wrk, 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 {
        uint32_t                *wlb, *wlp, *wle;
        unsigned                wlr;
@@ -772,13 +784,15 @@ void EXP_Clr(struct exp *e);
 
 double EXP_Ttl(const struct req *, const struct exp*);
 double EXP_When(const struct exp *exp);
-void EXP_Insert(struct objcore *oc);
-void EXP_Inject(struct objcore *oc, struct lru *lru);
+void EXP_Insert(struct worker *wrk, struct objcore *oc);
+void EXP_Inject(struct worker *wrk, struct objcore *oc, struct lru *lru);
 void EXP_Init(void);
 void EXP_Rearm(struct objcore *, double now, double ttl, double grace,
     double keep);
 void EXP_Touch(struct objcore *oc, double now);
 int EXP_NukeOne(struct worker *wrk, struct lru *lru);
+void EXP_Reg_Callback(struct exp_callback *cb);
+void EXP_Dereg_Callback(struct exp_callback *cb);
 
 /* cache_fetch.c */
 enum vbf_fetch_mode_e {
diff --git a/bin/varnishd/cache/cache_expire.c 
b/bin/varnishd/cache/cache_expire.c
index 79a8d2f..be5ffc0 100644
--- a/bin/varnishd/cache/cache_expire.c
+++ b/bin/varnishd/cache/cache_expire.c
@@ -52,10 +52,47 @@ struct exp_priv {
        VTAILQ_HEAD(,objcore)           inbox;
        struct binheap                  *heap;
        pthread_cond_t                  condvar;
+
+       VTAILQ_HEAD(,exp_callback)      cb_list;
+       pthread_rwlock_t                cb_mtx;
 };
 
 static struct exp_priv *exphdl;
 
+static void
+exp_insert_cb(struct worker *wrk, struct objcore *oc)
+{
+       struct exp_callback *cb;
+
+       if (VTAILQ_EMPTY(&exphdl->cb_list))
+               return;
+
+       AZ(pthread_rwlock_rdlock(&exphdl->cb_mtx));
+       VTAILQ_FOREACH(cb, &exphdl->cb_list, list) {
+               CHECK_OBJ_NOTNULL(cb, EXP_CALLBACK_MAGIC);
+               if (cb->cb_insert)
+                       cb->cb_insert(wrk, oc, cb->priv);
+       }
+       AZ(pthread_rwlock_unlock(&exphdl->cb_mtx));
+}
+
+static void
+exp_remove_cb(struct worker *wrk, struct objcore *oc)
+{
+       struct exp_callback *cb;
+
+       if (VTAILQ_EMPTY(&exphdl->cb_list))
+               return;
+
+       AZ(pthread_rwlock_rdlock(&exphdl->cb_mtx));
+       VTAILQ_FOREACH(cb, &exphdl->cb_list, list) {
+               CHECK_OBJ_NOTNULL(cb, EXP_CALLBACK_MAGIC);
+               if (cb->cb_remove)
+                       cb->cb_remove(wrk, oc, cb->priv);
+       }
+       AZ(pthread_rwlock_unlock(&exphdl->cb_mtx));
+}
+
 /*--------------------------------------------------------------------
  * struct exp manipulations
  */
@@ -130,9 +167,10 @@ exp_mail_it(struct objcore *oc)
  */
 
 void
-EXP_Inject(struct objcore *oc, struct lru *lru)
+EXP_Inject(struct worker *wrk, struct objcore *oc, struct lru *lru)
 {
 
+       CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
        CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC);
 
        AZ(oc->exp_flags & (OC_EF_OFFLRU | OC_EF_INSERT | OC_EF_MOVE));
@@ -146,6 +184,8 @@ EXP_Inject(struct objcore *oc, struct lru *lru)
        oc->timer_when = EXP_When(&oc->exp);
        Lck_Unlock(&lru->mtx);
 
+       exp_insert_cb(wrk, oc);
+
        exp_mail_it(oc);
 }
 
@@ -157,10 +197,11 @@ EXP_Inject(struct objcore *oc, struct lru *lru)
  */
 
 void
-EXP_Insert(struct objcore *oc)
+EXP_Insert(struct worker *wrk, struct objcore *oc)
 {
        struct lru *lru;
 
+       CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
        CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC);
        HSH_Ref(oc);
 
@@ -177,6 +218,8 @@ EXP_Insert(struct objcore *oc)
        oc->exp_flags |= OC_EF_MOVE;
        Lck_Unlock(&lru->mtx);
 
+       exp_insert_cb(wrk, oc);
+
        exp_mail_it(oc);
 }
 
@@ -344,6 +387,32 @@ EXP_NukeOne(struct worker *wrk, struct lru *lru)
        return (1);
 }
 
+void
+EXP_Reg_Callback(struct exp_callback *cb)
+{
+       CHECK_OBJ_NOTNULL(cb, EXP_CALLBACK_MAGIC);
+       AZ(pthread_rwlock_wrlock(&exphdl->cb_mtx));
+       VTAILQ_INSERT_TAIL(&exphdl->cb_list, cb, list);
+       AZ(pthread_rwlock_unlock(&exphdl->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(&exphdl->cb_mtx));
+       VTAILQ_FOREACH(cb2, &exphdl->cb_list, list) {
+               CHECK_OBJ_NOTNULL(cb2, EXP_CALLBACK_MAGIC);
+               if (cb2 == cb)
+                       break;
+       }
+       AN(cb2);
+       VTAILQ_REMOVE(&exphdl->cb_list, cb2, list);
+       AZ(pthread_rwlock_unlock(&exphdl->cb_mtx));
+}
+
 /*--------------------------------------------------------------------
  * Handle stuff in the inbox
  */
@@ -385,6 +454,7 @@ exp_inbox(struct exp_priv *ep, struct objcore *oc, double 
now)
                        binheap_delete(ep->heap, oc->timer_idx);
                }
                assert(oc->timer_idx == BINHEAP_NOIDX);
+               exp_remove_cb(ep->wrk, oc);
                (void)HSH_DerefObjCore(ep->wrk, &oc);
                return;
        }
@@ -464,6 +534,7 @@ exp_expire(struct exp_priv *ep, double now)
        CHECK_OBJ_NOTNULL(oc->objhead, OBJHEAD_MAGIC);
        VSLb(&ep->vsl, SLT_ExpKill, "EXP_Expired x=%u t=%.0f",
            ObjGetXID(ep->wrk, oc), EXP_Ttl(NULL, &oc->exp) - now);
+       exp_remove_cb(ep->wrk, oc);
        (void)HSH_DerefObjCore(ep->wrk, &oc);
        return (0);
 }
@@ -545,6 +616,8 @@ EXP_Init(void)
        Lck_New(&ep->mtx, lck_exp);
        AZ(pthread_cond_init(&ep->condvar, NULL));
        VTAILQ_INIT(&ep->inbox);
+       AZ(pthread_rwlock_init(&ep->cb_mtx, NULL));
+       VTAILQ_INIT(&ep->cb_list);
        exphdl = ep;
        WRK_BgThread(&pt, "cache-timeout", exp_thread, ep);
 }
diff --git a/bin/varnishd/cache/cache_hash.c b/bin/varnishd/cache/cache_hash.c
index de35e8a..686d398 100644
--- a/bin/varnishd/cache/cache_hash.c
+++ b/bin/varnishd/cache/cache_hash.c
@@ -693,7 +693,7 @@ HSH_Unbusy(struct worker *wrk, struct objcore *oc)
 
        if (!(oc->flags & OC_F_PRIVATE)) {
                BAN_NewObjCore(oc);
-               EXP_Insert(oc);
+               EXP_Insert(wrk, oc);
                AN(oc->exp_flags & OC_EF_EXP);
                AN(oc->ban);
        }
diff --git a/bin/varnishd/storage/storage_persistent_silo.c 
b/bin/varnishd/storage/storage_persistent_silo.c
index 8d02ed3..8119aad 100644
--- a/bin/varnishd/storage/storage_persistent_silo.c
+++ b/bin/varnishd/storage/storage_persistent_silo.c
@@ -166,7 +166,7 @@ smp_load_seg(struct worker *wrk, const struct smp_sc *sc,
                oc->ban = BAN_RefBan(oc, so->ban, sc->tailban);
                HSH_Insert(wrk, so->hash, oc);
                oc->exp = so->exp;
-               EXP_Inject(oc, sg->lru);
+               EXP_Inject(wrk, oc, sg->lru);
                sg->nobj++;
        }
        Pool_Sumstat(wrk);
-- 
2.1.4


_______________________________________________
varnish-dev mailing list
[email protected]
https://www.varnish-cache.org/lists/mailman/listinfo/varnish-dev

Reply via email to