]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: connection: add a new receive flag : CO_RFL_BUF_WET
authorWilly Tarreau <w@1wt.eu>
Tue, 19 Jun 2018 04:23:38 +0000 (06:23 +0200)
committerWilly Tarreau <w@1wt.eu>
Thu, 19 Jul 2018 14:23:41 +0000 (16:23 +0200)
With this flag we introduce the notion of "dry" vs "wet" buffers : some
demultiplexers like the H2 mux require as much room as possible for some
operations that are not retryable like decoding a headers frame. For this
they need to know if the buffer is congested with data scheduled for
leaving soon or not. Since the new API will not provide this information
in the buffer itself, the caller must indicate it. We never need to know
the amount of such data, just the fact that the buffer is not in its
optimal condition to be used for receipt. This "CO_RFL_BUF_WET" flag is
used to mention that such outgoing data are still pending in the buffer
and that a sensitive receiver should better let it "dry" before using it.

include/types/connection.h
src/mux_h2.c
src/stream_interface.c

index 13cbf7300fd354f676f308511b9785a3c67b1d4f..624e01e5139a4a37b0c6bc4df9d41861157a58f9 100644 (file)
@@ -243,7 +243,12 @@ enum {
        CO_SRC_BIND        = 0x0008,    /* bind to a specific source address when connecting */
 };
 
-/* flags that can be passed to xprt->snd_buf() */
+/* flags that can be passed to xprt->rcv_buf() and mux->rcv_buf() */
+enum {
+       CO_RFL_BUF_WET     = 0x0001,    /* Buffer still has some output data present */
+};
+
+/* flags that can be passed to xprt->snd_buf() and mux->snd_buf() */
 enum {
        CO_SFL_MSG_MORE    = 0x0001,    /* More data to come afterwards */
        CO_SFL_STREAMER    = 0x0002,    /* Producer is continuously streaming data */
index 250eae210cec7832ff717907969de1b12838c3cb..207589b55be5c528028c0353c67fd6bd11dca73a 100644 (file)
@@ -2614,7 +2614,7 @@ static void h2_shutw(struct conn_stream *cs, enum cs_shw_mode mode)
  * proceed. Stream errors are reported in h2s->errcode and connection errors
  * in h2c->errcode.
  */
-static int h2_frt_decode_headers(struct h2s *h2s, struct buffer *buf, int count)
+static int h2_frt_decode_headers(struct h2s *h2s, struct buffer *buf, int count, int flags)
 {
        struct h2c *h2c = h2s->h2c;
        const uint8_t *hdrs = (uint8_t *)h2c->dbuf->p;
@@ -2689,7 +2689,7 @@ static int h2_frt_decode_headers(struct h2s *h2s, struct buffer *buf, int count)
         * always empty except maybe for trailers, so these operations almost
         * never happen.
         */
-       if (unlikely(buf->o)) {
+       if (flags & CO_RFL_BUF_WET) {
                /* need to let the output buffer flush and
                 * mark the buffer for later wake up.
                 */
@@ -2775,7 +2775,7 @@ static int h2_frt_decode_headers(struct h2s *h2s, struct buffer *buf, int count)
  * frame header and ensured that the frame was complete or the buffer full. It
  * changes the frame state to FRAME_A once done.
  */
-static int h2_frt_transfer_data(struct h2s *h2s, struct buffer *buf, int count)
+static int h2_frt_transfer_data(struct h2s *h2s, struct buffer *buf, int count, int flags)
 {
        struct h2c *h2c = h2s->h2c;
        int block1, block2;
@@ -2937,11 +2937,11 @@ static size_t h2_rcv_buf(struct conn_stream *cs, struct buffer *buf, size_t coun
 
        switch (h2c->dft) {
        case H2_FT_HEADERS:
-               ret = h2_frt_decode_headers(h2s, buf, count);
+               ret = h2_frt_decode_headers(h2s, buf, count, flags);
                break;
 
        case H2_FT_DATA:
-               ret = h2_frt_transfer_data(h2s, buf, count);
+               ret = h2_frt_transfer_data(h2s, buf, count, flags);
                break;
 
        default:
index 0afcb972cd8a9efd3fd698f9df5e10f3c84be5bd..2677b2f0ce99407e7052243c54fc2b617f89c9d3 100644 (file)
@@ -1189,7 +1189,7 @@ static void si_cs_recv_cb(struct conn_stream *cs)
                        break;
                }
 
-               ret = conn->mux->rcv_buf(cs, ic->buf, max, 0);
+               ret = conn->mux->rcv_buf(cs, ic->buf, max, co_data(ic) ? CO_RFL_BUF_WET : 0);
                if (cs->flags & CS_FL_RCV_MORE)
                        si->flags |= SI_FL_WAIT_ROOM;