[master] 6179e31 fix a race in the backend probe code
Poul-Henning Kamp
phk at FreeBSD.org
Mon Jun 29 12:23:43 CEST 2015
commit 6179e316776ba8aae31a1b5dfe7ae4d226e0e15e
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date: Mon Jun 29 10:23:00 2015 +0000
fix a race in the backend probe code
Might be relevant to #1753
diff --git a/bin/varnishd/cache/cache_backend.h b/bin/varnishd/cache/cache_backend.h
index d1613f4..489cccb 100644
--- a/bin/varnishd/cache/cache_backend.h
+++ b/bin/varnishd/cache/cache_backend.h
@@ -82,7 +82,7 @@ struct backend {
};
/*---------------------------------------------------------------------
- * Backend connection -- private to cache_backend*.c
+ * Backend connection -- private to cache_backend*.c
*/
struct vbc {
diff --git a/bin/varnishd/cache/cache_backend_poll.c b/bin/varnishd/cache/cache_backend_poll.c
index 2cc9673..8060bb7 100644
--- a/bin/varnishd/cache/cache_backend_poll.c
+++ b/bin/varnishd/cache/cache_backend_poll.c
@@ -323,6 +323,7 @@ vbp_task(struct worker *wrk, void *priv)
CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
CAST_OBJ_NOTNULL(vt, priv, VBP_TARGET_MAGIC);
+ AN(vt->running);
AN(vt->req);
assert(vt->req_len > 0);
@@ -332,10 +333,17 @@ vbp_task(struct worker *wrk, void *priv)
vbp_update_backend(vt);
Lck_Lock(&vbp_mtx);
- if (vt->running < 0)
+ if (vt->running < 0) {
+ assert(vt->heap_idx == BINHEAP_NOIDX);
vbp_delete(vt);
- else
+ } else {
vt->running = 0;
+ if (vt->heap_idx != BINHEAP_NOIDX) {
+ vt->due = VTIM_real() + vt->interval;
+ binheap_delete(vbp_heap, vt->heap_idx);
+ binheap_insert(vbp_heap, vt);
+ }
+ }
Lck_Unlock(&vbp_mtx);
}
@@ -350,37 +358,31 @@ vbp_thread(struct worker *wrk, void *priv)
CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
AZ(priv);
+ Lck_Lock(&vbp_mtx);
while (1) {
- Lck_Lock(&vbp_mtx);
- while (1) {
- now = VTIM_real();
- vt = binheap_root(vbp_heap);
- if (vt == NULL) {
- nxt = 8.192 + now;
- } else if (vt->due > now) {
- nxt = vt->due;
- vt = NULL;
- } else {
- binheap_delete(vbp_heap, vt->heap_idx);
+ now = VTIM_real();
+ vt = binheap_root(vbp_heap);
+ if (vt == NULL) {
+ nxt = 8.192 + now;
+ (void)Lck_CondWait(&vbp_cond, &vbp_mtx, nxt);
+ } else if (vt->due > now) {
+ nxt = vt->due;
+ vt = NULL;
+ (void)Lck_CondWait(&vbp_cond, &vbp_mtx, nxt);
+ } else {
+ binheap_delete(vbp_heap, vt->heap_idx);
+ vt->due = now + vt->interval;
+ if (!vt->running) {
vt->running = 1;
- vt->due = now + vt->interval;
- binheap_insert(vbp_heap, vt);
- nxt = 0.0;
- break;
+ vt->task.func = vbp_task;
+ vt->task.priv = vt;
+ if (Pool_Task_Any(&vt->task, TASK_QUEUE_REQ))
+ vt->running = 0;
}
- (void)Lck_CondWait(&vbp_cond, &vbp_mtx, nxt);
- }
- Lck_Unlock(&vbp_mtx);
- vt->task.func = vbp_task;
- vt->task.priv = vt;
-
- if (Pool_Task_Any(&vt->task, TASK_QUEUE_REQ)) {
- Lck_Lock(&vbp_mtx);
- vt->running = 0;
- Lck_Unlock(&vbp_mtx);
- // XXX: ehh... ?
+ binheap_insert(vbp_heap, vt);
}
}
+ Lck_Unlock(&vbp_mtx);
NEEDLESS_RETURN(NULL);
}
@@ -582,8 +584,10 @@ VBP_Remove(struct backend *be)
vt = NULL;
}
Lck_Unlock(&vbp_mtx);
- if (vt != NULL)
+ if (vt != NULL) {
+ assert(vt->heap_idx == BINHEAP_NOIDX);
vbp_delete(vt);
+ }
}
/*-------------------------------------------------------------------*/
@@ -597,6 +601,9 @@ vbp_cmp(void *priv, const void *a, const void *b)
CAST_OBJ_NOTNULL(aa, a, VBP_TARGET_MAGIC);
CAST_OBJ_NOTNULL(bb, b, VBP_TARGET_MAGIC);
+ if (aa->running && !bb->running)
+ return (0);
+
return (aa->due < bb->due);
}
More information about the varnish-commit
mailing list