MEDIUM: h2: enable connection polling for send when a cs wants to emit

A conn_stream indicates its intent to send by setting the WR_ENA flag
and calling mux->update_poll(). There's no synchronous write so the only
way to emit a response from a stream is to proceed this way. The sender
h2s is then queued into the h2c's send_list if it was not yet queued.

Once the connection is ready, it will enter its send() callback to visit
writers, calling their data->send_cb() callback to complete the operation
using mux->snd_buf().

Also we enable polling if the mux contains data and wasn't enabled. This
may happen just after a response has been transmitted using chk_snd().
It likely is incomplete for now and should probably be refined.
This commit is contained in:
Willy Tarreau 2017-10-17 10:26:19 +02:00
parent 52eed75ced
commit 1d393228e0

View File

@ -938,6 +938,36 @@ static struct conn_stream *h2_attach(struct connection *conn)
*/
static void h2_update_poll(struct conn_stream *cs)
{
struct h2s *h2s = cs->ctx;
if (!h2s)
return;
/* Note: the stream and stream-int code doesn't allow us to perform a
* synchronous send() here unfortunately, because this code is called
* as si_update() from the process_stream() context. This means that
* we have to queue the current cs and defer its processing after the
* connection's cs list is processed anyway.
*/
if (cs->flags & CS_FL_DATA_WR_ENA) {
if (LIST_ISEMPTY(&h2s->list)) {
if (LIST_ISEMPTY(&h2s->h2c->send_list) &&
!h2s->h2c->mbuf->o && // not yet subscribed
!(cs->conn->flags & CO_FL_SOCK_WR_SH))
conn_xprt_want_send(cs->conn);
LIST_ADDQ(&h2s->h2c->send_list, &h2s->list);
}
}
else if (!LIST_ISEMPTY(&h2s->list)) {
LIST_DEL(&h2s->list);
LIST_INIT(&h2s->list);
h2s->flags &= ~(H2_SF_BLK_MBUSY | H2_SF_BLK_MROOM | H2_SF_BLK_MFCTL);
}
/* this can happen from within si_chk_snd() */
if (h2s->h2c->mbuf->o && !(cs->conn->flags & CO_FL_XPRT_WR_ENA))
conn_xprt_want_send(cs->conn);
}
/*