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

Commit 96619e6

Browse files
committed
h2: Keep track of streams entering waiting lists
But operate on a different objhead reference guarded by the h2_sess lock instead. This will allow coordination with the h2 session thread.
1 parent ab4a13e commit 96619e6

4 files changed

Lines changed: 70 additions & 1 deletion

File tree

bin/varnishd/cache/cache.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -471,11 +471,13 @@ struct req {
471471
void *transport_priv;
472472

473473
VTAILQ_ENTRY(req) w_list;
474+
VTAILQ_ENTRY(req) t_list;
474475

475476
struct objcore *body_oc;
476477

477-
/* The busy objhead we sleep on */
478+
/* The busy objhead we sleep on, referenced up to twice */
478479
struct objhead *hash_objhead;
480+
struct objhead *transport_objhead;
479481

480482
/* Built Vary string */
481483
uint8_t *vary_b;

bin/varnishd/http2/cache_http2.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ struct h2_req {
134134
int counted;
135135
struct h2_sess *h2sess;
136136
struct req *req;
137+
VTAILQ_HEAD(, req) waitinglist;
137138
double t_send;
138139
double t_winupd;
139140
pthread_cond_t *cond;

bin/varnishd/http2/cache_http2_proto.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,7 @@ h2_new_req(struct h2_sess *h2, unsigned stream, struct req *req)
159159
r2->r_window = h2->local_settings.initial_window_size;
160160
r2->t_window = h2->remote_settings.initial_window_size;
161161
req->transport_priv = r2;
162+
VTAILQ_INIT(&r2->waitinglist);
162163
Lck_Lock(&h2->sess->mtx);
163164
if (stream)
164165
h2->open_streams++;
@@ -182,6 +183,7 @@ h2_del_req(struct worker *wrk, struct h2_req *r2)
182183
ASSERT_RXTHR(h2);
183184
sp = h2->sess;
184185
Lck_Lock(&sp->mtx);
186+
assert(VTAILQ_EMPTY(&r2->waitinglist));
185187
assert(h2->refcnt > 0);
186188
--h2->refcnt;
187189
/* XXX: PRIORITY reshuffle */

bin/varnishd/http2/cache_http2_session.c

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
#include <stdio.h>
3737

3838
#include "cache/cache_transport.h"
39+
#include "cache/cache_objhead.h"
3940
#include "http2/cache_http2.h"
4041

4142
#include "vend.h"
@@ -438,6 +439,67 @@ h2_new_session(struct worker *wrk, void *arg)
438439
wrk->vsl = NULL;
439440
}
440441

442+
/**********************************************************************
443+
*/
444+
445+
static void
446+
h2_top_waitlist(struct worker *wrk, struct req *req)
447+
{
448+
struct objhead *oh;
449+
struct h2_req *r2;
450+
451+
CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
452+
CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
453+
oh = req->hash_objhead;
454+
CHECK_OBJ_NOTNULL(oh, OBJHEAD_MAGIC);
455+
CAST_OBJ_NOTNULL(r2, req->top->topreq->transport_priv, H2_REQ_MAGIC);
456+
457+
if (DO_DEBUG(DBG_WAITINGLIST))
458+
VSLb(req->vsl, SLT_Debug, "on h2 waiting list <%p>", r2);
459+
460+
Lck_AssertHeld(&oh->mtx);
461+
AN(req->waitinglist);
462+
AZ(req->wrk);
463+
464+
assert(oh->refcnt > 0);
465+
oh->refcnt++;
466+
467+
Lck_Lock(&r2->h2sess->sess->mtx);
468+
AZ(req->transport_objhead);
469+
req->transport_objhead = oh;
470+
VTAILQ_INSERT_TAIL(&r2->waitinglist, req, t_list);
471+
Lck_Unlock(&r2->h2sess->sess->mtx);
472+
}
473+
474+
static void
475+
h2_top_reembark(struct worker *wrk, struct req *req)
476+
{
477+
struct objhead *oh;
478+
struct h2_req *r2;
479+
480+
CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
481+
CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
482+
CAST_OBJ_NOTNULL(r2, req->top->topreq->transport_priv, H2_REQ_MAGIC);
483+
484+
if (DO_DEBUG(DBG_WAITINGLIST))
485+
VSLb(req->vsl, SLT_Debug, "off h2 waiting list <%p>", r2);
486+
487+
Lck_Lock(&r2->h2sess->sess->mtx);
488+
VTAILQ_REMOVE(&r2->waitinglist, req, t_list);
489+
oh = req->transport_objhead;
490+
req->transport_objhead = NULL;
491+
Lck_Unlock(&r2->h2sess->sess->mtx);
492+
493+
CHECK_OBJ_NOTNULL(oh, OBJHEAD_MAGIC);
494+
Lck_Lock(&oh->mtx);
495+
AN(req->hash_objhead);
496+
AZ(req->waitinglist);
497+
AZ(req->wrk);
498+
assert(oh->refcnt > 1);
499+
oh->refcnt--;
500+
Lck_Unlock(&oh->mtx);
501+
}
502+
441503
struct transport HTTP2_transport = {
442504
.name = "HTTP/2",
443505
.magic = TRANSPORT_MAGIC,
@@ -447,4 +509,6 @@ struct transport HTTP2_transport = {
447509
.req_body = h2_req_body,
448510
.req_fail = h2_req_fail,
449511
.sess_panic = h2_sess_panic,
512+
.top_waitlist = h2_top_waitlist,
513+
.top_reembark = h2_top_reembark,
450514
};

0 commit comments

Comments
 (0)