diff --git a/include/haproxy/mux_h1-t.h b/include/haproxy/mux_h1-t.h index 5f4cd7f5f..a0b64a9da 100644 --- a/include/haproxy/mux_h1-t.h +++ b/include/haproxy/mux_h1-t.h @@ -31,13 +31,14 @@ /* Flags indicating why writing output data are blocked */ #define H1C_F_OUT_ALLOC 0x00000001 /* mux is blocked on lack of output buffer */ #define H1C_F_OUT_FULL 0x00000002 /* mux is blocked on output buffer full */ -/* 0x00000004 - 0x00000008 unused */ +#define H1C_F_OUT_MAYALLOC 0x00000004 /* mux was just unblocked and may try to alloc out again */ /* Flags indicating why reading input data are blocked. */ +#define H1C_F_IN_MAYALLOC 0x00000008 /* mux was just unblocked and may try to alloc in again */ #define H1C_F_IN_ALLOC 0x00000010 /* mux is blocked on lack of input buffer */ #define H1C_F_IN_FULL 0x00000020 /* mux is blocked on input buffer full */ #define H1C_F_IN_SALLOC 0x00000040 /* mux is blocked on lack of stream's request buffer */ -/* 0x00000080 unused */ +#define H1C_F_IN_SMAYALLOC 0x00000080 /* mux was just unblocked and may try to alloc strm again */ #define H1C_F_EOS 0x00000100 /* End-of-stream seen on the H1 connection (read0 detected) */ #define H1C_F_ERR_PENDING 0x00000200 /* A write error was detected (block sends but not reads) */ @@ -66,12 +67,12 @@ static forceinline char *h1c_show_flags(char *buf, size_t len, const char *delim /* prologue */ _(0); /* flags */ - _(H1C_F_OUT_ALLOC, _(H1C_F_OUT_FULL, - _(H1C_F_IN_ALLOC, _(H1C_F_IN_FULL, _(H1C_F_IN_SALLOC, + _(H1C_F_OUT_ALLOC, _(H1C_F_OUT_FULL, _(H1C_F_OUT_MAYALLOC, + _(H1C_F_IN_MAYALLOC, _(H1C_F_IN_ALLOC, _(H1C_F_IN_FULL, _(H1C_F_IN_SALLOC, _(H1C_F_IN_SMAYALLOC, _(H1C_F_EOS, _(H1C_F_ERR_PENDING, _(H1C_F_ERROR, _(H1C_F_SILENT_SHUT, _(H1C_F_ABRT_PENDING, _(H1C_F_ABRTED, _(H1C_F_WANT_FASTFWD, _(H1C_F_WAIT_NEXT_REQ, _(H1C_F_UPG_H2C, _(H1C_F_CO_MSG_MORE, - _(H1C_F_CO_STREAMER, _(H1C_F_CANT_FASTFWD, _(H1C_F_IS_BACK)))))))))))))))))); + _(H1C_F_CO_STREAMER, _(H1C_F_CANT_FASTFWD, _(H1C_F_IS_BACK))))))))))))))))))))); /* epilogue */ _(~0U); return buf; diff --git a/src/mux_h1.c b/src/mux_h1.c index 79b6afef7..8515b36b9 100644 --- a/src/mux_h1.c +++ b/src/mux_h1.c @@ -501,21 +501,27 @@ static int h1_buf_available(void *target) { struct h1c *h1c = target; - if ((h1c->flags & H1C_F_IN_ALLOC) && h1_recv_allowed(h1c)) { - TRACE_STATE("unblocking h1c, ibuf allocated", H1_EV_H1C_RECV|H1_EV_H1C_BLK|H1_EV_H1C_WAKE, h1c->conn); + if (h1c->flags & H1C_F_IN_ALLOC) { h1c->flags &= ~H1C_F_IN_ALLOC; - tasklet_wakeup(h1c->wait_event.tasklet); + h1c->flags |= H1C_F_IN_MAYALLOC; } if ((h1c->flags & H1C_F_OUT_ALLOC) && h1c->h1s) { - TRACE_STATE("unblocking h1s, obuf allocated", H1_EV_TX_DATA|H1_EV_H1S_BLK|H1_EV_STRM_WAKE, h1c->conn, h1c->h1s); + TRACE_STATE("unblocking h1s, obuf allocatable", H1_EV_TX_DATA|H1_EV_H1S_BLK|H1_EV_STRM_WAKE, h1c->conn, h1c->h1s); h1c->flags &= ~H1C_F_OUT_ALLOC; + h1c->flags |= H1C_F_OUT_MAYALLOC; h1_wake_stream_for_send(h1c->h1s); } if ((h1c->flags & H1C_F_IN_SALLOC) && h1c->h1s) { - TRACE_STATE("unblocking h1c, stream rxbuf allocated", H1_EV_H1C_RECV|H1_EV_H1C_BLK|H1_EV_H1C_WAKE, h1c->conn); + TRACE_STATE("unblocking h1c, stream rxbuf allocatable", H1_EV_H1C_RECV|H1_EV_H1C_BLK|H1_EV_H1C_WAKE, h1c->conn); h1c->flags &= ~H1C_F_IN_SALLOC; + h1c->flags |= H1C_F_IN_SMAYALLOC; + tasklet_wakeup(h1c->wait_event.tasklet); + } + + if ((h1c->flags & H1C_F_IN_MAYALLOC) && h1_recv_allowed(h1c)) { + TRACE_STATE("unblocking h1c, ibuf allocatable", H1_EV_H1C_RECV|H1_EV_H1C_BLK|H1_EV_H1C_WAKE, h1c->conn); tasklet_wakeup(h1c->wait_event.tasklet); } @@ -537,6 +543,9 @@ static inline struct buffer *h1_get_ibuf(struct h1c *h1c) b_queue(DB_MUX_RX, &h1c->buf_wait, h1c, h1_buf_available); h1c->flags |= H1C_F_IN_ALLOC; } + else + h1c->flags &= ~H1C_F_IN_MAYALLOC; + return buf; } @@ -552,6 +561,9 @@ static inline struct buffer *h1_get_obuf(struct h1c *h1c) b_queue(DB_MUX_TX, &h1c->buf_wait, h1c, h1_buf_available); h1c->flags |= H1C_F_OUT_ALLOC; } + else + h1c->flags &= ~H1C_F_OUT_MAYALLOC; + return buf; } @@ -568,6 +580,9 @@ static inline struct buffer *h1_get_rxbuf(struct h1s *h1s) b_queue(DB_SE_RX, &h1c->buf_wait, h1c, h1_buf_available); h1c->flags |= H1C_F_IN_SALLOC; } + else + h1c->flags &= ~H1C_F_IN_SMAYALLOC; + return buf; } @@ -932,7 +947,8 @@ static void h1s_destroy(struct h1s *h1s) h1_release_buf(h1c, &h1s->rxbuf); h1c->flags &= ~(H1C_F_WANT_FASTFWD| - H1C_F_OUT_FULL|H1C_F_OUT_ALLOC|H1C_F_IN_SALLOC| + H1C_F_OUT_FULL|H1C_F_OUT_ALLOC|H1C_F_OUT_MAYALLOC| + H1C_F_IN_SALLOC|H1C_F_IN_SMAYALLOC| H1C_F_CO_MSG_MORE|H1C_F_CO_STREAMER); if (!(h1c->flags & (H1C_F_EOS|H1C_F_ERR_PENDING|H1C_F_ERROR|H1C_F_ABRT_PENDING|H1C_F_ABRTED)) && /* No error/read0/abort */