From 902ba7e2bc25c1426d34bf3ec2441d751db9df95 Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Tue, 24 May 2022 08:49:24 +0200 Subject: [PATCH] CLEANUP: stconn: use a single function to know if SC may send to SE sc_is_send_allowed() is now used everywhere instead of the combination of cs_tx_endp_ready() && !cs_tx_blocked(). There's no place where we need them individually thus it's simpler. The test was placed in cs_util as we'll complete it later. --- include/haproxy/cs_utils.h | 10 ++++++++++ src/applet.c | 2 +- src/conn_stream.c | 3 +-- src/stream.c | 6 ++---- 4 files changed, 14 insertions(+), 7 deletions(-) diff --git a/include/haproxy/cs_utils.h b/include/haproxy/cs_utils.h index 9f5463d42..22b21b27b 100644 --- a/include/haproxy/cs_utils.h +++ b/include/haproxy/cs_utils.h @@ -341,4 +341,14 @@ static inline const char *cs_state_str(int state) } } +/* indicates if the connector may send data to the endpoint, that is, the + * endpoint is both willing to receive data and ready to do so. This is only + * used with applets so there's always a stream attached to this connector. + */ +__attribute__((warn_unused_result)) +static inline int sc_is_send_allowed(const struct stconn *sc) +{ + return cs_tx_endp_ready(sc) && !cs_tx_blocked(sc); +} + #endif /* _HAPROXY_CS_UTILS_H */ diff --git a/src/applet.c b/src/applet.c index fe1fc625d..1af0dbddf 100644 --- a/src/applet.c +++ b/src/applet.c @@ -246,7 +246,7 @@ struct task *task_run_applet(struct task *t, void *context, unsigned int state) if (rate >= 100000 && app->call_rate.prev_ctr && // looped more than 100k times over last second ((b_size(sc_ib(cs)) && se_fl_test(app->sedesc, SE_FL_RXBLK_BUFF)) || // asks for a buffer which is present (b_size(sc_ib(cs)) && !b_data(sc_ib(cs)) && se_fl_test(app->sedesc, SE_FL_RXBLK_ROOM)) || // asks for room in an empty buffer - (b_data(sc_ob(cs)) && cs_tx_endp_ready(cs) && !cs_tx_blocked(cs)) || // asks for data already present + (b_data(sc_ob(cs)) && sc_is_send_allowed(cs)) || // asks for data already present (!b_data(sc_ib(cs)) && b_data(sc_ob(cs)) && // didn't return anything ... (sc_oc(cs)->flags & (CF_WRITE_PARTIAL|CF_SHUTW_NOW)) == CF_SHUTW_NOW))) { // ... and left data pending after a shut stream_dump_and_crash(&app->obj_type, read_freq_ctr(&app->call_rate)); diff --git a/src/conn_stream.c b/src/conn_stream.c index 9ad525869..e3c206680 100644 --- a/src/conn_stream.c +++ b/src/conn_stream.c @@ -1951,8 +1951,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)) || - (cs_tx_endp_ready(cs) && !cs_tx_blocked(cs))) + if ((cs_rx_endp_ready(cs) && !cs_rx_blocked(cs)) || sc_is_send_allowed(cs)) appctx_wakeup(__sc_appctx(cs)); return 0; } diff --git a/src/stream.c b/src/stream.c index c0e49b652..e6b197897 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)) || - (cs_tx_endp_ready(scf) && !cs_tx_blocked(scf))) + if ((cs_rx_endp_ready(scf) && !cs_rx_blocked(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)) || - (cs_tx_endp_ready(scb) && !cs_tx_blocked(scb))) + if ((cs_rx_endp_ready(scb) && !cs_rx_blocked(scb)) || sc_is_send_allowed(scb)) appctx_wakeup(__sc_appctx(scb)); } }