[PATCH 11/25] Lock busyobj when doing late object header changes (end of FetchBody creating a Content-Length header), and when copying the object headers in RES_BuildHTTP.

Martin Blix Grydeland martin at varnish-software.com
Sun Jan 22 18:53:17 CET 2012


Add general lock functions for busyobjs
---
 bin/varnishd/cache/cache.h         |    2 ++
 bin/varnishd/cache/cache_busyobj.c |   14 ++++++++++++++
 bin/varnishd/cache/cache_center.c  |   10 +++++++++-
 bin/varnishd/cache/cache_fetch.c   |    4 ++++
 4 files changed, 29 insertions(+), 1 deletions(-)

diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h
index b59a217..da06965 100644
--- a/bin/varnishd/cache/cache.h
+++ b/bin/varnishd/cache/cache.h
@@ -750,6 +750,8 @@ struct busyobj *VBO_GetBusyObj(struct worker *wrk);
 struct busyobj *VBO_RefBusyObj(struct busyobj *busyobj);
 unsigned VBO_DerefBusyObj(struct worker *wrk, struct busyobj **busyobj);
 void VBO_Free(struct vbo **vbo);
+void VBO_LockBusyObj(struct busyobj *busyobj);
+void VBO_UnlockBusyObj(struct busyobj *busyobj);
 void VBO_StreamStopped(struct busyobj *busyobj);
 void VBO_StreamWait(struct busyobj *busyobj);
 void VBO_StreamData(struct busyobj *busyobj);
diff --git a/bin/varnishd/cache/cache_busyobj.c b/bin/varnishd/cache/cache_busyobj.c
index 7651999..6eec464 100644
--- a/bin/varnishd/cache/cache_busyobj.c
+++ b/bin/varnishd/cache/cache_busyobj.c
@@ -209,6 +209,20 @@ VBO_DerefBusyObj(struct worker *wrk, struct busyobj **pbo)
 	return (r);
 }
 
+void
+VBO_LockBusyObj(struct busyobj *busyobj)
+{
+	if (busyobj->use_locks)
+		Lck_Lock(&busyobj->vbo->mtx);
+}
+
+void
+VBO_UnlockBusyObj(struct busyobj *busyobj)
+{
+	if (busyobj->use_locks)
+		Lck_Unlock(&busyobj->vbo->mtx);
+}
+
 /* Signal that the fetch thread has stopped */
 void
 VBO_StreamStopped(struct busyobj *busyobj)
diff --git a/bin/varnishd/cache/cache_center.c b/bin/varnishd/cache/cache_center.c
index 55e06c6..386012c 100644
--- a/bin/varnishd/cache/cache_center.c
+++ b/bin/varnishd/cache/cache_center.c
@@ -285,7 +285,15 @@ cnt_prepresp(struct sess *sp, struct worker *wrk, struct req *req)
 		req->obj->last_use = req->t_resp;	/* XXX: locking ? */
 	}
 	http_Setup(req->resp, req->ws);
-	RES_BuildHttp(sp);
+	if (wrk->busyobj != NULL) {
+		/* We are streaming, read the object headers while
+		 * holding the lock as the fetching thread might
+		 * update these headers (set Content-Length) */
+		VBO_LockBusyObj(wrk->busyobj);
+		RES_BuildHttp(sp);
+		VBO_UnlockBusyObj(wrk->busyobj);
+	} else
+		RES_BuildHttp(sp);
 	VCL_deliver_method(sp);
 	switch (req->handling) {
 	case VCL_RET_DELIVER:
diff --git a/bin/varnishd/cache/cache_fetch.c b/bin/varnishd/cache/cache_fetch.c
index f69d80f..d5ae4d5 100644
--- a/bin/varnishd/cache/cache_fetch.c
+++ b/bin/varnishd/cache/cache_fetch.c
@@ -616,9 +616,13 @@ FetchBody(struct worker *wrk, struct busyobj *bo)
 	}
 
 	if (mklen > 0) {
+		/* Lock the busyobj during late header changes, as a
+		 * streaming client may be reading these */
+		VBO_LockBusyObj(bo);
 		http_Unset(obj->http, H_Content_Length);
 		http_PrintfHeader(wrk, bo->vbc->vsl_id, obj->http,
 		    "Content-Length: %zd", obj->len);
+		VBO_UnlockBusyObj(bo);
 	}
 
 	if (cls)
-- 
1.7.4.1




More information about the varnish-dev mailing list