Skip to content
This repository was archived by the owner on Feb 16, 2026. It is now read-only.

Commit b75b21b

Browse files
committed
transport: Add a waitlist method
It comes with new functions hsh_waitlist() and hsh_reembark() that centralize the logic. The waitlist method is meant for client-facing transport to register when requests enter and leave a waiting list.
1 parent def50e6 commit b75b21b

2 files changed

Lines changed: 64 additions & 27 deletions

File tree

bin/varnishd/cache/cache_hash.c

Lines changed: 62 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,63 @@ hsh_insert_busyobj(const struct worker *wrk, struct objhead *oh)
355355
return (oc);
356356
}
357357

358+
/*---------------------------------------------------------------------
359+
*/
360+
361+
static void
362+
hsh_waitlist(struct worker *wrk, struct req *req, struct objhead *oh)
363+
{
364+
365+
CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
366+
CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
367+
CHECK_OBJ_NOTNULL(oh, OBJHEAD_MAGIC);
368+
Lck_AssertHeld(&oh->mtx);
369+
AZ(req->hash_ignore_busy);
370+
AZ(req->hash_objhead);
371+
372+
DSLb(DBG_WAITINGLIST, "on waiting list <%p>", oh);
373+
374+
/*
375+
* The objhead reference transfers to the sess, we get it
376+
* back when the sess comes off the waiting list and
377+
* calls us again
378+
*/
379+
req->hash_objhead = oh;
380+
req->wrk = NULL;
381+
req->waitinglist = 1;
382+
383+
if (req->top->topreq->transport->waitlist != NULL)
384+
req->top->topreq->transport->waitlist(wrk, req);
385+
}
386+
387+
static void
388+
hsh_reembark(struct worker *wrk, struct req *req)
389+
{
390+
391+
CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
392+
CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
393+
394+
if (DO_DEBUG(DBG_WAITINGLIST))
395+
VSLb(req->vsl, SLT_Debug, "off waiting list");
396+
397+
if (!IS_TOPREQ(req) && req->top->topreq->transport->reembark != NULL)
398+
req->top->topreq->transport->reembark(wrk, req);
399+
400+
if (req->transport->reembark != NULL) {
401+
// For ESI includes
402+
req->transport->reembark(wrk, req);
403+
return;
404+
}
405+
406+
/*
407+
* We ignore the queue limits which apply to new
408+
* requests because if we fail to reschedule there
409+
* may be vmod_privs to cleanup and we need a proper
410+
* workerthread for that.
411+
*/
412+
AZ(Pool_Task(req->sp->pool, req->task, TASK_QUEUE_RUSH));
413+
}
414+
358415
/*---------------------------------------------------------------------
359416
*/
360417

@@ -577,21 +634,11 @@ HSH_Lookup(struct req *req, struct objcore **ocp, struct objcore **bocp)
577634

578635
/* There are one or more busy objects, wait for them */
579636
VTAILQ_INSERT_TAIL(&oh->waitinglist, req, w_list);
637+
hsh_waitlist(wrk, req, oh);
580638

581-
AZ(req->hash_ignore_busy);
582-
583-
/*
584-
* The objhead reference transfers to the sess, we get it
585-
* back when the sess comes off the waiting list and
586-
* calls us again
587-
*/
588-
req->hash_objhead = oh;
589-
req->wrk = NULL;
590-
req->waitinglist = 1;
591-
592-
if (DO_DEBUG(DBG_WAITINGLIST))
593-
VSLb(req->vsl, SLT_Debug, "on waiting list <%p>", oh);
594-
639+
/* NOTE OBS: We are going on the waitinglist. No changing of
640+
* anything on struct req after releasing the mutex, as we may be
641+
* rescheduled immediately. */
595642
Lck_Unlock(&oh->mtx);
596643

597644
wrk->stats->busy_sleep++;
@@ -648,19 +695,7 @@ hsh_rush2(struct worker *wrk, struct rush *r)
648695
req = VTAILQ_FIRST(&r->reqs);
649696
CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
650697
VTAILQ_REMOVE(&r->reqs, req, w_list);
651-
DSL(DBG_WAITINGLIST, req->vsl->wid, "off waiting list");
652-
if (req->transport->reembark != NULL) {
653-
// For ESI includes
654-
req->transport->reembark(wrk, req);
655-
} else {
656-
/*
657-
* We ignore the queue limits which apply to new
658-
* requests because if we fail to reschedule there
659-
* may be vmod_privs to cleanup and we need a proper
660-
* workerthread for that.
661-
*/
662-
AZ(Pool_Task(req->sp->pool, req->task, TASK_QUEUE_RUSH));
663-
}
698+
hsh_reembark(wrk, req);
664699
}
665700
}
666701

bin/varnishd/cache/cache_transport.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ typedef void vtr_req_body_f (struct req *);
4343
typedef void vtr_sess_panic_f (struct vsb *, const struct sess *);
4444
typedef void vtr_req_panic_f (struct vsb *, const struct req *);
4545
typedef void vtr_req_fail_f (struct req *, stream_close_t);
46+
typedef void vtr_waitlist_f (struct worker *, struct req *);
4647
typedef void vtr_reembark_f (struct worker *, struct req *);
4748
typedef int vtr_minimal_response_f (struct req *, uint16_t status);
4849

@@ -63,6 +64,7 @@ struct transport {
6364
vtr_deliver_f *deliver;
6465
vtr_sess_panic_f *sess_panic;
6566
vtr_req_panic_f *req_panic;
67+
vtr_waitlist_f *waitlist; /* only for req_top */
6668
vtr_reembark_f *reembark;
6769
vtr_minimal_response_f *minimal_response;
6870

0 commit comments

Comments
 (0)