[master] 7098d0482 vcl_vrt: When assigning directors, first reference, then dereference

Nils Goroll nils.goroll at uplex.de
Fri Dec 13 10:08:12 UTC 2024


commit 7098d0482d9508f47935641b9a559644aad27489
Author: Nils Goroll <nils.goroll at uplex.de>
Date:   Fri Dec 13 11:04:35 2024 +0100

    vcl_vrt: When assigning directors, first reference, then dereference
    
    Dridis previous commit b825f55f348595cfc24f5eee92b86ecf2e880924 made me realize
    that there exists another case with the same effect: *dst could be the director
    holding the last reference to src (for example, when src is a backend of *dst),
    so we should reference first, then dereference.

diff --git a/bin/varnishd/cache/cache_vrt_vcl.c b/bin/varnishd/cache/cache_vrt_vcl.c
index 33ba68241..264ad3446 100644
--- a/bin/varnishd/cache/cache_vrt_vcl.c
+++ b/bin/varnishd/cache/cache_vrt_vcl.c
@@ -332,18 +332,15 @@ void
 VRT_Assign_Backend(VCL_BACKEND *dst, VCL_BACKEND src)
 {
 	struct vcldir *vdir;
+	VCL_BACKEND tmp;
 
 	AN(dst);
 	CHECK_OBJ_ORNULL((*dst), DIRECTOR_MAGIC);
 	CHECK_OBJ_ORNULL(src, DIRECTOR_MAGIC);
 	if (*dst == src)
 		return;
-	if (*dst != NULL) {
-		vdir = (*dst)->vdir;
-		CHECK_OBJ_NOTNULL(vdir, VCLDIR_MAGIC);
-		if (!(vdir->flags & VDIR_FLG_NOREFCNT))
-			(void)vcldir_deref(vdir);
-	}
+	tmp = *dst;
+	*dst = src;
 	if (src != NULL) {
 		vdir = src->vdir;
 		CHECK_OBJ_NOTNULL(vdir, VCLDIR_MAGIC);
@@ -354,7 +351,12 @@ VRT_Assign_Backend(VCL_BACKEND *dst, VCL_BACKEND src)
 			Lck_Unlock(&vdir->dlck);
 		}
 	}
-	*dst = src;
+	if (tmp != NULL) {
+		vdir = tmp->vdir;
+		CHECK_OBJ_NOTNULL(vdir, VCLDIR_MAGIC);
+		if (!(vdir->flags & VDIR_FLG_NOREFCNT))
+			(void)vcldir_deref(vdir);
+	}
 }
 
 void


More information about the varnish-commit mailing list