[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