[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