[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