From 1666c0ca0e69337fc6598618a54da99329ad9a4c Mon Sep 17 00:00:00 2001 From: Christopher Faulet Date: Thu, 5 Mar 2026 18:03:34 +0100 Subject: [PATCH] MEDIUM: stconn: Merge all .chk_rcv() callback functions in sc_chk_rcv() sc_chk_rcv() is no longer relying on .chk_rcv() callback functions. Everything was merged in sc_chk_rcv() with a test on the app type. --- include/haproxy/sc_strm.h | 27 ++------------------------ src/stconn.c | 40 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 25 deletions(-) diff --git a/include/haproxy/sc_strm.h b/include/haproxy/sc_strm.h index c0e91201d..ebc2becbd 100644 --- a/include/haproxy/sc_strm.h +++ b/include/haproxy/sc_strm.h @@ -36,6 +36,8 @@ void sc_update_rx(struct stconn *sc); void sc_update_tx(struct stconn *sc); +void sc_chk_rcv(struct stconn *sc); + struct task *sc_conn_io_cb(struct task *t, void *ctx, unsigned int state); int sc_conn_sync_recv(struct stconn *sc); int sc_conn_sync_send(struct stconn *sc); @@ -360,31 +362,6 @@ static inline int sc_is_recv_allowed(const struct stconn *sc) return !(sc->flags & (SC_FL_WONT_READ|SC_FL_NEED_BUFF|SC_FL_NEED_ROOM)); } -/* 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 - * point in order to avoid useless repeated wakeups. - * It will then call ->chk_rcv() to enable receipt of new data. - */ -static inline void sc_chk_rcv(struct stconn *sc) -{ - if (sc_ep_test(sc, SE_FL_APPLET_NEED_CONN) && - sc_state_in(sc_opposite(sc)->state, SC_SB_RDY|SC_SB_EST|SC_SB_DIS|SC_SB_CLO)) { - sc_ep_clr(sc, SE_FL_APPLET_NEED_CONN); - sc_ep_report_read_activity(sc); - } - - if (!sc_is_recv_allowed(sc)) - return; - - if (!sc_state_in(sc->state, SC_SB_RDY|SC_SB_EST)) - return; - - sc_ep_set(sc, SE_FL_HAVE_NO_DATA); - if (likely(sc->app_ops->chk_rcv)) - sc->app_ops->chk_rcv(sc); -} - /* Calls chk_snd on the endpoint using the data layer */ static inline void sc_chk_snd(struct stconn *sc) { diff --git a/src/stconn.c b/src/stconn.c index 0c641e50f..a1aedeb31 100644 --- a/src/stconn.c +++ b/src/stconn.c @@ -675,6 +675,46 @@ static void sc_app_abort(struct stconn *sc) task_wakeup(sc_strm_task(sc), TASK_WOKEN_IO); } + +/* 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 + * point in order to avoid useless repeated wakeups. + * It will then woken the right entity to enable receipt of new data. + */ +void sc_chk_rcv(struct stconn *sc) +{ + BUG_ON(!sc_strm(sc)); + + if (sc_ep_test(sc, SE_FL_APPLET_NEED_CONN) && + sc_state_in(sc_opposite(sc)->state, SC_SB_RDY|SC_SB_EST|SC_SB_DIS|SC_SB_CLO)) { + sc_ep_clr(sc, SE_FL_APPLET_NEED_CONN); + sc_ep_report_read_activity(sc); + } + + if (!sc_is_recv_allowed(sc)) + return; + + if (!sc_state_in(sc->state, SC_SB_RDY|SC_SB_EST)) + return; + + sc_ep_set(sc, SE_FL_HAVE_NO_DATA); + + /* (re)start reading */ + if (sc_ep_test(sc, SE_FL_T_MUX)) { + if (sc_state_in(sc->state, SC_SB_CON|SC_SB_RDY|SC_SB_EST)) + tasklet_wakeup(sc->wait_event.tasklet, TASK_WOKEN_IO); + } + else if (sc_ep_test(sc, SE_FL_T_APPLET)) { + if (!sc_ep_have_ff_data(sc_opposite(sc))) + appctx_wakeup(__sc_appctx(sc)); + } + else { + if (!(sc->flags & SC_FL_DONT_WAKE)) + task_wakeup(sc_strm_task(sc), TASK_WOKEN_IO); + } +} + /* * This function performs a shutdown-write on a detached stream connector in a * connected or init state (it does nothing for other states). It either shuts