[4.0] 653a9ea Keep the fetch thread busyobj pointer-ref separate from the client thread pointer-ref, and deref it on thread scheduling failure.

Lasse Karstensen lkarsten at varnish-software.com
Mon Jan 19 16:38:36 CET 2015


commit 653a9ea1af81fdcdf16c34f7d910da6a77400132
Author: Martin Blix Grydeland <martin at varnish-software.com>
Date:   Tue Nov 18 13:12:58 2014 +0100

    Keep the fetch thread busyobj pointer-ref separate from the client thread pointer-ref, and deref it on thread scheduling failure.
    
    The code tried to deref the same pointer twice, which failed because
    the VBO_DerefBusyobj() will clear the pointer when called. Separating
    allows calling VBO_DerefBusyobj() for each of them.
    
    Fixes: #1628
    (cherry picked from commit 7746e30e2c53cf55f0f2525bb3f49c9ee83e9611)
    
    Conflicts:
    	bin/varnishd/cache/cache_fetch.c

diff --git a/bin/varnishd/cache/cache_fetch.c b/bin/varnishd/cache/cache_fetch.c
index 18c937d..f87c1bd 100644
--- a/bin/varnishd/cache/cache_fetch.c
+++ b/bin/varnishd/cache/cache_fetch.c
@@ -896,7 +896,7 @@ void
 VBF_Fetch(struct worker *wrk, struct req *req, struct objcore *oc,
     struct object *oldobj, enum vbf_fetch_mode_e mode)
 {
-	struct busyobj *bo;
+	struct busyobj *bo, *bo_fetch;
 	const char *how;
 
 	CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
@@ -920,6 +920,7 @@ VBF_Fetch(struct worker *wrk, struct req *req, struct objcore *oc,
 	VSLb(req->vsl, SLT_Link, "bereq %u %s",
 	    bo->vsl->wid & VSL_IDENTMASK, how);
 
+	bo_fetch = bo;
 	bo->refcount = 2;
 
 	oc->busyobj = bo;
@@ -949,7 +950,7 @@ VBF_Fetch(struct worker *wrk, struct req *req, struct objcore *oc,
 	AZ(bo->req);
 	bo->req = req;
 
-	bo->fetch_task.priv = bo;
+	bo->fetch_task.priv = bo_fetch;
 	bo->fetch_task.func = vbf_fetch_thread;
 
 	if (Pool_Task(wrk->pool, &bo->fetch_task, POOL_QUEUE_FRONT)) {
@@ -957,17 +958,21 @@ VBF_Fetch(struct worker *wrk, struct req *req, struct objcore *oc,
 		(void)vbf_stp_fail(req->wrk, bo);
 		if (bo->ims_obj != NULL)
 			(void)HSH_DerefObj(&wrk->stats, &bo->ims_obj);
-		VBO_DerefBusyObj(wrk, &bo);
-	} else if (mode == VBF_BACKGROUND) {
-		VBO_waitstate(bo, BOS_REQ_DONE);
+		VBO_DerefBusyObj(wrk, &bo_fetch);
 	} else {
-		VBO_waitstate(bo, BOS_STREAM);
-		if (bo->state == BOS_FAILED) {
-			AN((oc->flags & OC_F_FAILED));
+		bo_fetch = NULL; /* ref transferred to fetch thread */
+		if (mode == VBF_BACKGROUND) {
+			VBO_waitstate(bo, BOS_REQ_DONE);
 		} else {
-			AZ(bo->fetch_objcore->flags & OC_F_BUSY);
+			VBO_waitstate(bo, BOS_STREAM);
+			if (bo->state == BOS_FAILED) {
+				AN((oc->flags & OC_F_FAILED));
+			} else {
+				AZ(bo->fetch_objcore->flags & OC_F_BUSY);
+			}
 		}
 	}
+	AZ(bo_fetch);
 	VSLb_ts_req(req, "Fetch", W_TIM_real(wrk));
 	VBO_DerefBusyObj(wrk, &bo);
 	THR_SetBusyobj(NULL);



More information about the varnish-commit mailing list