diff --git a/include/haproxy/conn_stream-t.h b/include/haproxy/conn_stream-t.h index 599ee81de..6ec87c83a 100644 --- a/include/haproxy/conn_stream-t.h +++ b/include/haproxy/conn_stream-t.h @@ -78,10 +78,10 @@ enum se_flags { SE_FL_RXBLK_CHAN = 0x04000000, /* the channel doesn't want the CS to introduce data */ SE_FL_RXBLK_BUFF = 0x08000000, /* CS waits for a buffer allocation to complete */ SE_FL_RXBLK_ROOM = 0x10000000, /* CS waits for more buffer room to store incoming data */ + SE_FL_RXBLK_ANY = 0x1C000000, /* any of the RXBLK flags above */ + SE_FL_APP_MASK = 0x1fe00000, /* Mask for flags set by the app layer */ /* unused 0x20000000,*/ SE_FL_APPLET_NEED_CONN = 0x40000000, /* applet is waiting for the other side to (fail to) connect */ - SE_FL_RXBLK_ANY = 0x5C000000, /* any of the RXBLK flags above */ - SE_FL_APP_MASK = 0x5fe00000, /* Mask for flags set by the app layer */ }; /* stconn flags */ diff --git a/include/haproxy/cs_utils.h b/include/haproxy/cs_utils.h index 9aceb9c52..0da4f43fc 100644 --- a/include/haproxy/cs_utils.h +++ b/include/haproxy/cs_utils.h @@ -296,13 +296,15 @@ static inline void cs_chk_rcv(struct stconn *cs) { struct channel *ic = sc_ic(cs); - if (sc_ep_test(cs, SE_FL_APPLET_NEED_CONN) && cs_state_in(cs_opposite(cs)->state, SC_SB_RDY|SC_SB_EST|SC_SB_DIS|SC_SB_CLO)) + if (sc_ep_test(cs, SE_FL_APPLET_NEED_CONN) && + cs_state_in(cs_opposite(cs)->state, SC_SB_RDY|SC_SB_EST|SC_SB_DIS|SC_SB_CLO)) sc_ep_clr(cs, SE_FL_APPLET_NEED_CONN); if (ic->flags & CF_SHUTR) return; - if (cs_rx_blocked(cs) || !cs_rx_endp_ready(cs)) + if (sc_ep_test(cs, SE_FL_APPLET_NEED_CONN) || + cs_rx_blocked(cs) || !cs_rx_endp_ready(cs)) return; if (!cs_state_in(cs->state, SC_SB_RDY|SC_SB_EST)) diff --git a/src/conn_stream.c b/src/conn_stream.c index 85c3b82ba..b60a9c59c 100644 --- a/src/conn_stream.c +++ b/src/conn_stream.c @@ -1178,7 +1178,7 @@ static void cs_notify(struct stconn *cs) cs_chk_rcv(cs); cs_chk_rcv(cso); - if (ic->flags & CF_SHUTR || cs_rx_blocked(cs)) { + if (ic->flags & CF_SHUTR || sc_ep_test(cs, SE_FL_APPLET_NEED_CONN) || cs_rx_blocked(cs)) { ic->rex = TICK_ETERNITY; } else if ((ic->flags & (CF_SHUTR|CF_READ_PARTIAL)) == CF_READ_PARTIAL) { @@ -1925,7 +1925,7 @@ static int cs_applet_process(struct stconn *cs) /* automatically mark the applet having data available if it reported * begin blocked by the channel. */ - if (cs_rx_blocked(cs)) + if (cs_rx_blocked(cs) || sc_ep_test(cs, SE_FL_APPLET_NEED_CONN)) cs_rx_endp_more(cs); /* update the stream connector, channels, and possibly wake the stream up */ @@ -1937,7 +1937,8 @@ static int cs_applet_process(struct stconn *cs) * appctx but in the case the task is not in runqueue we may have to * wakeup the appctx immediately. */ - if ((cs_rx_endp_ready(cs) && !cs_rx_blocked(cs) && !(ic->flags & CF_SHUTR)) || + if ((cs_rx_endp_ready(cs) && !cs_rx_blocked(cs) && + !sc_ep_test(cs, SE_FL_APPLET_NEED_CONN) && !(ic->flags & CF_SHUTR)) || sc_is_send_allowed(cs)) appctx_wakeup(__sc_appctx(cs)); return 0; diff --git a/src/stream.c b/src/stream.c index 606a8681b..1a28900eb 100644 --- a/src/stream.c +++ b/src/stream.c @@ -1543,11 +1543,13 @@ static void stream_update_both_cs(struct stream *s) * handled at the latest moment. */ if (sc_appctx(scf)) { - if ((cs_rx_endp_ready(scf) && !cs_rx_blocked(scf) && !(req->flags & CF_SHUTR)) || sc_is_send_allowed(scf)) + if ((cs_rx_endp_ready(scf) && !cs_rx_blocked(scf) && !sc_ep_test(scf, SE_FL_APPLET_NEED_CONN) && + !(req->flags & CF_SHUTR)) || sc_is_send_allowed(scf)) appctx_wakeup(__sc_appctx(scf)); } if (sc_appctx(scb)) { - if ((cs_rx_endp_ready(scb) && !cs_rx_blocked(scb) && !(res->flags & CF_SHUTR)) || sc_is_send_allowed(scb)) + if ((cs_rx_endp_ready(scb) && !cs_rx_blocked(scb) && !sc_ep_test(scb, SE_FL_APPLET_NEED_CONN) && + !(res->flags & CF_SHUTR)) || sc_is_send_allowed(scb)) appctx_wakeup(__sc_appctx(scb)); } }