]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: h2: enable connection polling for send when a cs wants to emit
authorWilly Tarreau <w@1wt.eu>
Tue, 17 Oct 2017 08:26:19 +0000 (10:26 +0200)
committerWilly Tarreau <w@1wt.eu>
Tue, 31 Oct 2017 17:16:18 +0000 (18:16 +0100)
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.

src/mux_h2.c

index 08cc574ef229c6f16f57823152bb1e5886016cae..f05c2693937031513e95e90be0428b17476c89ad 100644 (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);
 }
 
 /*