[master] b8d4eb8 Hand FetchBody() its own busyobj->refcount, and have it release it when done.

Poul-Henning Kamp phk at varnish-cache.org
Mon Mar 12 13:28:07 CET 2012


commit b8d4eb8a23d1971aaef3fe087d024b7f1dd78df9
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Mon Mar 12 12:27:34 2012 +0000

    Hand FetchBody() its own busyobj->refcount, and have it release it
    when done.

diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h
index 48bdac0..99c66c3 100644
--- a/bin/varnishd/cache/cache.h
+++ b/bin/varnishd/cache/cache.h
@@ -725,7 +725,7 @@ double BAN_Time(const struct ban *ban);
 /* cache_busyobj.c */
 void VBO_Init(void);
 struct busyobj *VBO_GetBusyObj(struct worker *wrk);
-void VBO_RefBusyObj(const struct busyobj *busyobj);
+void VBO_RefBusyObj(struct busyobj *busyobj);
 void VBO_DerefBusyObj(struct worker *wrk, struct busyobj **busyobj);
 void VBO_Free(struct busyobj **vbo);
 
diff --git a/bin/varnishd/cache/cache_busyobj.c b/bin/varnishd/cache/cache_busyobj.c
index 601272f..8de928a 100644
--- a/bin/varnishd/cache/cache_busyobj.c
+++ b/bin/varnishd/cache/cache_busyobj.c
@@ -135,21 +135,16 @@ VBO_GetBusyObj(struct worker *wrk)
 	return (bo);
 }
 
-#if 0
 void
-VBO_RefBusyObj(const struct busyobj *busyobj)
+VBO_RefBusyObj(struct busyobj *bo)
 {
-	struct vbo *vbo;
-
-	CHECK_OBJ_NOTNULL(busyobj, BUSYOBJ_MAGIC);
-	vbo = busyobj->vbo;
-	CHECK_OBJ_NOTNULL(vbo, VBO_MAGIC);
-	Lck_Lock(&vbo->mtx);
-	assert(vbo->refcount > 0);
-	vbo->refcount++;
-	Lck_Unlock(&vbo->mtx);
+
+	CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
+	Lck_Lock(&bo->mtx);
+	assert(bo->refcount > 0);
+	bo->refcount++;
+	Lck_Unlock(&bo->mtx);
 }
-#endif
 
 void
 VBO_DerefBusyObj(struct worker *wrk, struct busyobj **pbo)
@@ -157,7 +152,7 @@ VBO_DerefBusyObj(struct worker *wrk, struct busyobj **pbo)
 	struct busyobj *bo;
 	unsigned r;
 
-	CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
+	CHECK_OBJ_ORNULL(wrk, WORKER_MAGIC);
 	AN(pbo);
 	bo = *pbo;
 	*pbo = NULL;
@@ -175,7 +170,7 @@ VBO_DerefBusyObj(struct worker *wrk, struct busyobj **pbo)
 	memset(&bo->refcount, 0,
 	    sizeof *bo - offsetof(struct busyobj, refcount));
 
-	if (cache_param->bo_cache && wrk->nbo == NULL)
+	if (cache_param->bo_cache && wrk != NULL && wrk->nbo == NULL)
 		wrk->nbo = bo;
 	else
 		VBO_Free(&bo);
diff --git a/bin/varnishd/cache/cache_center.c b/bin/varnishd/cache/cache_center.c
index 7df47bb..aa07828 100644
--- a/bin/varnishd/cache/cache_center.c
+++ b/bin/varnishd/cache/cache_center.c
@@ -905,6 +905,10 @@ cnt_fetchbody(struct sess *sp, struct worker *wrk, struct req *req)
 
 	bo->fetch_task.func = FetchBody;
 	bo->fetch_task.priv = bo;
+
+	/* Gain a reference for FetchBody() */
+	VBO_RefBusyObj(bo);
+
 	if (Pool_Task(wrk->pool, &bo->fetch_task, POOL_NO_QUEUE))
 		FetchBody(wrk, bo);
 
@@ -912,8 +916,6 @@ cnt_fetchbody(struct sess *sp, struct worker *wrk, struct req *req)
 		(void)usleep(10000);
 	assert(bo->state >= BOS_FAILED);
 
-	http_Teardown(bo->bereq);
-	http_Teardown(bo->beresp);
 	bo->vfp = NULL;
 	assert(WRW_IsReleased(wrk));
 	AZ(bo->vbc);
diff --git a/bin/varnishd/cache/cache_fetch.c b/bin/varnishd/cache/cache_fetch.c
index e3bf6dc..a52201a 100644
--- a/bin/varnishd/cache/cache_fetch.c
+++ b/bin/varnishd/cache/cache_fetch.c
@@ -298,7 +298,7 @@ fetch_chunked(struct busyobj *bo, struct http_conn *htc)
 	do {
 		/* Skip leading whitespace */
 		do {
-			if (HTC_Read(htc, buf, 1) <= 0) 
+			if (HTC_Read(htc, buf, 1) <= 0)
 				return (FetchError(bo, "chunked read err"));
 		} while (vct_islws(buf[0]));
 
@@ -527,7 +527,13 @@ FetchHdr(struct sess *sp, int need_host_hdr, int sendbody)
 	return (0);
 }
 
-/*--------------------------------------------------------------------*/
+/*--------------------------------------------------------------------
+ * This function is either called by the requesting thread OR by a
+ * dedicated body-fetch work-thread.
+ *
+ * We get passed the busyobj in the priv arg, and we inherit a
+ * refcount on it, which we must release, when done fetching.
+ */
 
 void
 FetchBody(struct worker *wrk, void *priv)
@@ -623,6 +629,9 @@ FetchBody(struct worker *wrk, void *priv)
 	    bo->body_status, body_status(bo->body_status),
 	    cls, mklen);
 
+	http_Teardown(bo->bereq);
+	http_Teardown(bo->beresp);
+
 	if (bo->state == BOS_FAILED) {
 		wrk->stats.fetch_failed++;
 		VDI_CloseFd(&bo->vbc);
@@ -665,6 +674,7 @@ FetchBody(struct worker *wrk, void *priv)
 
 	}
 	bo->stats = NULL;
+	VBO_DerefBusyObj(NULL, &bo);
 }
 
 /*--------------------------------------------------------------------



More information about the varnish-commit mailing list