From 13d63afacd6e14dd5f5b698a00c81bea59c50f14 Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Wed, 25 May 2022 15:00:44 +0200 Subject: [PATCH] MINOR: stconn: add sc_is_recv_allowed() to check for ability to receive At plenty of places we combine multiple flags checks to determine if we can receive (endp_ready, rx_blocked, cf_shutr etc). Let's group them under a single function that is meant to replace existing tests. Some tests were only checking the rxblk flags at the connection level, so for now they were not converted, this requires a bit of auditing first, and probably a test to determine whether or not to check for cf_shutr (e.g. there is none if no stream is present). --- include/haproxy/cs_utils.h | 29 ++++++++++++++++++++++------- src/conn_stream.c | 6 ++---- src/stream.c | 6 ++---- 3 files changed, 26 insertions(+), 15 deletions(-) diff --git a/include/haproxy/cs_utils.h b/include/haproxy/cs_utils.h index 8ec217f2d..8593dd1f4 100644 --- a/include/haproxy/cs_utils.h +++ b/include/haproxy/cs_utils.h @@ -286,6 +286,27 @@ static inline void cs_shutw(struct stconn *cs) cs->app_ops->shutw(cs); } +/* Returns non-zero if the stream connector is allowed to receive from the + * endpoint, which means that no flag indicating a blocked channel, lack of + * buffer or room is set, and that the endpoint is not waiting for the + * application to complete a connection setup on the other side, and that + * the stream's channel is not shut for reads. This is only used by stream + * applications. + */ +__attribute__((warn_unused_result)) +static inline int sc_is_recv_allowed(const struct stconn *sc) +{ + struct channel *ic = sc_ic(sc); + + if (ic->flags & CF_SHUTR) + return 0; + + if (sc_ep_test(sc, SE_FL_APPLET_NEED_CONN)) + return 0; + + return cs_rx_endp_ready(sc) && !cs_rx_blocked(sc); +} + /* This is to be used after making some room available in a channel. It will * return without doing anything if the stream connector's RX path is blocked. * It will automatically mark the stream connector as busy processing the end @@ -294,17 +315,11 @@ static inline void cs_shutw(struct stconn *cs) */ 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)) sc_ep_clr(cs, SE_FL_APPLET_NEED_CONN); - if (ic->flags & CF_SHUTR) - return; - - if (sc_ep_test(cs, SE_FL_APPLET_NEED_CONN) || - cs_rx_blocked(cs) || !cs_rx_endp_ready(cs)) + if (!sc_is_recv_allowed(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 9904fba31..9ebc0c56e 100644 --- a/src/conn_stream.c +++ b/src/conn_stream.c @@ -1614,7 +1614,7 @@ int sc_conn_sync_recv(struct stconn *cs) if (cs->wait_event.events & SUB_RETRY_RECV) return 0; // already subscribed - if (!cs_rx_endp_ready(cs) || cs_rx_blocked(cs)) + if (!sc_is_recv_allowed(cs)) return 0; // already failed return sc_conn_recv(cs); @@ -1937,9 +1937,7 @@ 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) && - !sc_ep_test(cs, SE_FL_APPLET_NEED_CONN) && !(ic->flags & CF_SHUTR)) || - sc_is_send_allowed(cs)) + if (sc_is_recv_allowed(cs) || sc_is_send_allowed(cs)) appctx_wakeup(__sc_appctx(cs)); return 0; } diff --git a/src/stream.c b/src/stream.c index 64e2dd0e8..913f92559 100644 --- a/src/stream.c +++ b/src/stream.c @@ -1543,13 +1543,11 @@ 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) && !sc_ep_test(scf, SE_FL_APPLET_NEED_CONN) && - !(req->flags & CF_SHUTR)) || sc_is_send_allowed(scf)) + if (sc_is_recv_allowed(scf) || sc_is_send_allowed(scf)) appctx_wakeup(__sc_appctx(scf)); } if (sc_appctx(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)) + if (sc_is_recv_allowed(scb) || sc_is_send_allowed(scb)) appctx_wakeup(__sc_appctx(scb)); } }