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

Commit 91f367c

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 a2cfe91 commit 91f367c

4 files changed

Lines changed: 49 additions & 1 deletion

File tree

bin/varnishd/cache/cache.h

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

468468
VTAILQ_ENTRY(req) w_list;
469+
VTAILQ_ENTRY(req) t_list;
469470

470471
struct objcore *body_oc;
471472

472-
/* The busy objhead we sleep on */
473+
/* The busy objhead we sleep on, referenced up to twice */
473474
struct objhead *hash_objhead;
475+
struct objhead *transport_objhead;
474476

475477
/* Built Vary string */
476478
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: 43 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"
@@ -444,17 +445,59 @@ h2_new_session(struct worker *wrk, void *arg)
444445
static void
445446
h2_waitlist(struct worker *wrk, struct req *req)
446447
{
448+
struct objhead *oh;
449+
struct h2_req *r2;
447450

448451
CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
449452
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);
450472
}
451473

452474
static void
453475
h2_reembark(struct worker *wrk, struct req *req)
454476
{
477+
struct objhead *oh;
478+
struct h2_req *r2;
455479

456480
CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
457481
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);
458501

459502
if (IS_TOPREQ(req))
460503
AZ(Pool_Task(req->sp->pool, req->task, TASK_QUEUE_RUSH));

0 commit comments

Comments
 (0)