diff --git a/bin/varnishd/cache/cache_vrt_vcl.c b/bin/varnishd/cache/cache_vrt_vcl.c index 82e6e10a5d..f7339f9add 100644 --- a/bin/varnishd/cache/cache_vrt_vcl.c +++ b/bin/varnishd/cache/cache_vrt_vcl.c @@ -336,6 +336,8 @@ VRT_Assign_Backend(VCL_BACKEND *dst, VCL_BACKEND src) 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); @@ -373,7 +375,7 @@ VRT_LookupDirector(VRT_CTX, VCL_STRING name) { struct vcl *vcl; struct vcldir *vdir; - VCL_BACKEND dd, d = NULL; + VCL_BACKEND dir = NULL; CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); AN(name); @@ -386,15 +388,21 @@ VRT_LookupDirector(VRT_CTX, VCL_STRING name) Lck_Lock(&vcl_mtx); VTAILQ_FOREACH(vdir, &vcl->director_list, list) { - dd = vdir->dir; - if (strcmp(dd->vcl_name, name)) - continue; - d = dd; - break; + if (!strcmp(vdir->dir->vcl_name, name)) { + dir = vdir->dir; + break; + } } Lck_Unlock(&vcl_mtx); - return (d); + /* XXX: There is a race here between the supposedly incoming call + * to VRT_Assign_Backend() and the next vcldir_deref() call. + * + * Maybe the VRT_CTX could keep a ref of the last director lookup + * that would linger until the end of vcl_init. + */ + + return (dir); } /*--------------------------------------------------------------------*/