[master] af2f05d5a vdire: Wait for directors to retire before staring a new iteration
Nils Goroll
nils.goroll at uplex.de
Wed Jan 22 18:53:05 UTC 2025
commit af2f05d5a9783bc8571eb0b0936ca2db6d3edb7e
Author: Nils Goroll <nils.goroll at uplex.de>
Date: Mon Oct 28 16:27:41 2024 +0100
vdire: Wait for directors to retire before staring a new iteration
This is to prevent a potential pileup of resigned directors with a constant
stream of iterators coming on
diff --git a/bin/varnishd/cache/cache_vcl.c b/bin/varnishd/cache/cache_vcl.c
index c8c31014d..2140bc664 100644
--- a/bin/varnishd/cache/cache_vcl.c
+++ b/bin/varnishd/cache/cache_vcl.c
@@ -387,6 +387,7 @@ vdire_new(struct lock *mtx, const struct vcltemp **tempp)
VTAILQ_INIT(&vdire->directors);
VTAILQ_INIT(&vdire->resigning);
vdire->mtx = mtx;
+ PTOK(pthread_cond_init(&vdire->cond, NULL));
vdire->tempp = tempp;
return (vdire);
}
@@ -402,6 +403,8 @@ vdire_start_iter(struct vdire *vdire)
ASSERT_CLI();
Lck_Lock(vdire->mtx);
+ while (! VTAILQ_EMPTY(&vdire->resigning))
+ (void)Lck_CondWait(&vdire->cond, vdire->mtx);
vdire->iterating++;
Lck_Unlock(vdire->mtx);
}
@@ -425,6 +428,7 @@ vdire_end_iter(struct vdire *vdire)
VTAILQ_FOREACH(vdir, &resigning, resigning_list)
VTAILQ_REMOVE(&vdire->directors, vdir, directors_list);
temp = *vdire->tempp;
+ PTOK(pthread_cond_broadcast(&vdire->cond));
}
Lck_Unlock(vdire->mtx);
@@ -581,6 +585,14 @@ vcl_KillBackends(const struct vcl *vcl)
vdire = vcl->vdire;
CHECK_OBJ_NOTNULL(vdire, VDIRE_MAGIC);
+ /*
+ * ensure all retirement has finished (vdire_start_iter waits for it)
+ */
+ vdire_start_iter(vdire);
+ vdire_end_iter(vdire);
+ AZ(vdire->iterating);
+ assert(VTAILQ_EMPTY(&vdire->resigning));
+
/*
* Unlocked and sidelining vdire because no further directors can be added, and the
* remaining ones need to be able to remove themselves.
@@ -658,6 +670,7 @@ VCL_Close(struct vcl **vclp)
TAKE_OBJ_NOTNULL(vcl, vclp, VCL_MAGIC);
assert(VTAILQ_EMPTY(&vcl->filters));
AZ(dlclose(vcl->dlh));
+ PTOK(pthread_cond_destroy(&vcl->vdire->cond));
FREE_OBJ(vcl->vdire);
FREE_OBJ(vcl);
}
diff --git a/bin/varnishd/cache/cache_vcl.h b/bin/varnishd/cache/cache_vcl.h
index 7b7b28ce1..f7fc31b60 100644
--- a/bin/varnishd/cache/cache_vcl.h
+++ b/bin/varnishd/cache/cache_vcl.h
@@ -47,6 +47,8 @@ struct vdire {
struct vcldir_head resigning;
// vcl_mtx for now - to be refactored into separate mtx?
struct lock *mtx;
+ // to signal when iterators can enter again
+ pthread_cond_t cond;
const struct vcltemp **tempp;
};
More information about the varnish-commit
mailing list