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


_______________________________________________
varnish-dev mailing list
[email protected]
https://www.varnish-cache.org/lists/mailman/listinfo/varnish-dev

Reply via email to