MINOR: h2: keep a count of the number of conn_streams attached to the mux

The h2 mux only knows about the number of H2 streams which are not in a
CLOSED state. This is used for protocol compliance. But it doesn't hold
the number of really attached streams. It is a problem because depending
on scheduling, it is possible that more streams are attached to the mux
than the ones seen at the protocol level, due to some streams taking some
time to be detached. Let's add this count based on the conn_streams.

Note: this patch is part of a series of fixes which will have to be
backported to 1.8.
This commit is contained in:
Willy Tarreau 2018-07-19 09:04:05 +02:00
parent 17b4aa1adc
commit 7ac60e836a

View File

@ -113,7 +113,7 @@ struct h2c {
int timeout; /* idle timeout duration in ticks */ int timeout; /* idle timeout duration in ticks */
int shut_timeout; /* idle timeout duration in ticks after GOAWAY was sent */ int shut_timeout; /* idle timeout duration in ticks after GOAWAY was sent */
unsigned int nb_streams; /* number of streams in the tree */ unsigned int nb_streams; /* number of streams in the tree */
/* 32 bit hole here */ unsigned int nb_cs; /* number of attached conn_streams */
struct task *task; /* timeout management task */ struct task *task; /* timeout management task */
struct eb_root streams_by_id; /* all active streams by their ID */ struct eb_root streams_by_id; /* all active streams by their ID */
struct list send_list; /* list of blocked streams requesting to send */ struct list send_list; /* list of blocked streams requesting to send */
@ -352,6 +352,7 @@ static int h2c_frt_init(struct connection *conn)
h2c->rcvd_c = 0; h2c->rcvd_c = 0;
h2c->rcvd_s = 0; h2c->rcvd_s = 0;
h2c->nb_streams = 0; h2c->nb_streams = 0;
h2c->nb_cs = 0;
h2c->dbuf = &buf_empty; h2c->dbuf = &buf_empty;
h2c->dsi = -1; h2c->dsi = -1;
@ -632,6 +633,7 @@ static struct h2s *h2c_stream_new(struct h2c *h2c, int id)
h2s->cs = cs; h2s->cs = cs;
cs->ctx = h2s; cs->ctx = h2s;
h2c->nb_cs++;
if (stream_create_from_cs(cs) < 0) if (stream_create_from_cs(cs) < 0)
goto out_free_cs; goto out_free_cs;
@ -640,6 +642,7 @@ static struct h2s *h2c_stream_new(struct h2c *h2c, int id)
return h2s; return h2s;
out_free_cs: out_free_cs:
h2c->nb_cs--;
cs_free(cs); cs_free(cs);
out_close: out_close:
h2s_destroy(h2s); h2s_destroy(h2s);
@ -2441,6 +2444,7 @@ static void h2_detach(struct conn_stream *cs)
h2c = h2s->h2c; h2c = h2s->h2c;
h2s->cs = NULL; h2s->cs = NULL;
h2c->nb_cs--;
/* this stream may be blocked waiting for some data to leave (possibly /* this stream may be blocked waiting for some data to leave (possibly
* an ES or RST frame), so orphan it in this case. * an ES or RST frame), so orphan it in this case.
@ -3431,8 +3435,8 @@ static void h2_show_fd(struct chunk *msg, struct connection *conn)
node = eb32_next(node); node = eb32_next(node);
} }
chunk_appendf(msg, " st0=%d flg=0x%08x fctl_cnt=%d send_cnt=%d tree_cnt=%d orph_cnt=%d", chunk_appendf(msg, " st0=%d flg=0x%08x nbst=%u nbcs=%u fctl_cnt=%d send_cnt=%d tree_cnt=%d orph_cnt=%d",
h2c->st0, h2c->flags, fctl_cnt, send_cnt, tree_cnt, orph_cnt); h2c->st0, h2c->flags, h2c->nb_streams, h2c->nb_cs, fctl_cnt, send_cnt, tree_cnt, orph_cnt);
} }
/*******************************************************/ /*******************************************************/