mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-01-31 10:31:46 +00:00
MEDIUM: h2: start to implement the frames processing loop
The rcv_buf() callback now calls h2_process_demux() after an recv() call leaving some data in the buffer, and the snd_buf() callback calls h2_process_mux() to try to process pending data from streams.
This commit is contained in:
parent
5160683fc7
commit
bc933930a7
77
src/mux_h2.c
77
src/mux_h2.c
@ -576,6 +576,19 @@ static struct h2s *h2c_stream_new(struct h2c *h2c, int id)
|
||||
return h2s;
|
||||
}
|
||||
|
||||
/* process Rx frames to be demultiplexed */
|
||||
static void h2_process_demux(struct h2c *h2c)
|
||||
{
|
||||
}
|
||||
|
||||
/* process Tx frames from streams to be multiplexed. Returns > 0 if it reached
|
||||
* the end.
|
||||
*/
|
||||
static int h2_process_mux(struct h2c *h2c)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************/
|
||||
/* functions below are I/O callbacks from the connection */
|
||||
@ -619,7 +632,7 @@ static void h2_recv(struct connection *conn)
|
||||
if (buf->i == buf->size)
|
||||
h2c->flags |= H2_CF_DEM_DFULL;
|
||||
|
||||
/* FIXME: should we try to process streams here instead of doing it in ->wake ? */
|
||||
h2_process_demux(h2c);
|
||||
|
||||
/* after streams have been processed, we should have made some room */
|
||||
if (buf->i != buf->size)
|
||||
@ -631,8 +644,7 @@ static void h2_recv(struct connection *conn)
|
||||
static void h2_send(struct connection *conn)
|
||||
{
|
||||
struct h2c *h2c = conn->mux_ctx;
|
||||
|
||||
/* FIXME: should we try to process pending streams here instead of doing it in ->wake ? */
|
||||
int done;
|
||||
|
||||
if (conn->flags & CO_FL_ERROR)
|
||||
return;
|
||||
@ -642,29 +654,50 @@ static void h2_send(struct connection *conn)
|
||||
return;
|
||||
}
|
||||
|
||||
/* This loop is quite simple : it tries to fill as much as it can from
|
||||
* pending streams into the existing buffer until it's reportedly full
|
||||
* or the end of send requests is reached. Then it tries to send this
|
||||
* buffer's contents out, marks it not full if at least one byte could
|
||||
* be sent, and tries again.
|
||||
*
|
||||
* The snd_buf() function normally takes a "flags" argument which may
|
||||
* be made of a combination of CO_SFL_MSG_MORE to indicate that more
|
||||
* data immediately comes and CO_SFL_STREAMER to indicate that the
|
||||
* connection is streaming lots of data (used to increase TLS record
|
||||
* size at the expense of latency). The former can be sent any time
|
||||
* there's a buffer full flag, as it indicates at least one stream
|
||||
* attempted to send and failed so there are pending data. An
|
||||
* alternative would be to set it as long as there's an active stream
|
||||
* but that would be problematic for ACKs until we have an absolute
|
||||
* guarantee that all waiters have at least one byte to send. The
|
||||
* latter should possibly not be set for now.
|
||||
*/
|
||||
|
||||
done = 0;
|
||||
while (!done) {
|
||||
unsigned int flags = 0;
|
||||
|
||||
/* fill as much as we can into the current buffer */
|
||||
while (((h2c->flags & (H2_CF_MUX_MFULL|H2_CF_MUX_MALLOC)) == 0) && !done)
|
||||
done = h2_process_mux(h2c);
|
||||
|
||||
if (conn->flags & CO_FL_ERROR)
|
||||
break;
|
||||
|
||||
if (h2c->flags & (H2_CF_MUX_MFULL | H2_CF_DEM_MBUSY | H2_CF_DEM_MROOM))
|
||||
flags |= CO_SFL_MSG_MORE;
|
||||
|
||||
if (conn->xprt->snd_buf(conn, h2c->mbuf, flags) <= 0)
|
||||
break;
|
||||
|
||||
/* wrote at least one byte, the buffer is not full anymore */
|
||||
h2c->flags &= ~(H2_CF_MUX_MFULL | H2_CF_DEM_MROOM);
|
||||
}
|
||||
|
||||
if (conn->flags & CO_FL_SOCK_WR_SH) {
|
||||
/* output closed, nothing to send, clear the buffer to release it */
|
||||
h2c->mbuf->o = 0;
|
||||
}
|
||||
|
||||
/* pending response data, we need to try to send or subscribe to
|
||||
* writes. The snd_buf() function takes a "flags" argument which
|
||||
* may be made of a combination of CO_SFL_MSG_MORE to indicate
|
||||
* that more data immediately comes and CO_SFL_STREAMER to
|
||||
* indicate that the connection is streaming lots of data (used
|
||||
* to increase TLS record size at the expense of latency). The
|
||||
* former could be sent any time there's a buffer full flag, as
|
||||
* it indicates at least one stream attempted to send and failed
|
||||
* so there are pending data. And alternative would be to set it
|
||||
* as long as there's an active stream but that would be
|
||||
* problematic for ACKs. The latter should possibly not be set
|
||||
* for now.
|
||||
*/
|
||||
if (conn->xprt->snd_buf(conn, h2c->mbuf, 0) > 0)
|
||||
h2c->flags &= ~(H2_CF_MUX_MFULL | H2_CF_DEM_MROOM);
|
||||
|
||||
if (conn->flags & CO_FL_ERROR)
|
||||
return;
|
||||
}
|
||||
|
||||
/* call the wake up function of all streams attached to the connection */
|
||||
|
Loading…
Reference in New Issue
Block a user