diff --git a/bin/varnishd/cache/cache_backend.c b/bin/varnishd/cache/cache_backend.c index d5c5f4683ba..4e302b416d4 100644 --- a/bin/varnishd/cache/cache_backend.c +++ b/bin/varnishd/cache/cache_backend.c @@ -57,6 +57,7 @@ enum connwait_e { CW_DO_CONNECT = 1, CW_QUEUED, + CW_DEQUEUED, CW_BE_BUSY, }; @@ -150,14 +151,11 @@ vbe_connwait_signal_locked(struct backend *bp) } static void -vbe_connwait_dequeue(struct backend *bp, struct connwait *cw, int lock_it) +vbe_connwait_dequeue_locked(struct backend *bp, struct connwait *cw) { - if (lock_it) - Lck_Lock(bp->director->mtx); VTAILQ_REMOVE(&bp->cw_head, cw, cw_list); vbe_connwait_signal_locked(bp); - if (lock_it) - Lck_Unlock(bp->director->mtx); + cw->cw_state = CW_DEQUEUED; } /*-------------------------------------------------------------------- @@ -238,8 +236,11 @@ vbe_dir_getfd(VRT_CTX, struct worker *wrk, VCL_BACKEND dir, struct backend *bp, if (bo->htc == NULL) { VSLb(bo->vsl, SLT_FetchError, "out of workspace"); /* XXX: counter ? */ - if (cw->cw_state == CW_QUEUED) - vbe_connwait_dequeue(bp, cw, 1); + if (cw->cw_state == CW_QUEUED) { + Lck_Lock(bp->director->mtx); + vbe_connwait_dequeue_locked(bp, cw); + Lck_Unlock(bp->director->mtx); + } PTOK(pthread_cond_destroy(&cw->cw_cond)); return (NULL); } @@ -257,8 +258,11 @@ vbe_dir_getfd(VRT_CTX, struct worker *wrk, VCL_BACKEND dir, struct backend *bp, VRT_BACKEND_string(dir), err, VAS_errtxt(err)); VSC_C_main->backend_fail++; bo->htc = NULL; - if (cw->cw_state == CW_QUEUED) - vbe_connwait_dequeue(bp, cw, 1); + if (cw->cw_state == CW_QUEUED) { + Lck_Lock(bp->director->mtx); + vbe_connwait_dequeue_locked(bp, cw); + Lck_Unlock(bp->director->mtx); + } PTOK(pthread_cond_destroy(&cw->cw_cond)); return (NULL); } @@ -273,7 +277,7 @@ vbe_dir_getfd(VRT_CTX, struct worker *wrk, VCL_BACKEND dir, struct backend *bp, bp->vsc->conn++; bp->vsc->req++; if (cw->cw_state == CW_QUEUED) - vbe_connwait_dequeue(bp, cw, 0); + vbe_connwait_dequeue_locked(bp, cw); Lck_Unlock(bp->director->mtx);