[master] 7746e30 Keep the fetch thread busyobj pointer-ref separate from the client thread pointer-ref, and deref it on thread scheduling failure.
Martin Blix Grydeland
martin at varnish-software.com
Tue Nov 18 13:32:31 CET 2014
commit 7746e30e2c53cf55f0f2525bb3f49c9ee83e9611
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
diff --git a/bin/varnishd/cache/cache_fetch.c b/bin/varnishd/cache/cache_fetch.c
index 3fae2bf..08f253f 100644
--- a/bin/varnishd/cache/cache_fetch.c
+++ b/bin/varnishd/cache/cache_fetch.c
@@ -904,7 +904,7 @@ void
VBF_Fetch(struct worker *wrk, struct req *req, struct objcore *oc,
struct objcore *oldoc, enum vbf_fetch_mode_e mode)
{
- struct busyobj *bo;
+ struct busyobj *bo, *bo_fetch;
const char *how;
CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
@@ -927,6 +927,7 @@ VBF_Fetch(struct worker *wrk, struct req *req, struct objcore *oc,
THR_SetBusyobj(bo);
+ bo_fetch = bo;
bo->refcount = 2;
oc->busyobj = bo;
@@ -953,7 +954,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)) {
@@ -961,17 +962,21 @@ VBF_Fetch(struct worker *wrk, struct req *req, struct objcore *oc,
(void)vbf_stp_fail(req->wrk, bo);
if (bo->ims_oc != NULL)
(void)HSH_DerefObjCore(wrk, &bo->ims_oc);
- 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