]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: connection: track mux calls to report their allocation context
authorWilly Tarreau <w@1wt.eu>
Wed, 11 Mar 2026 09:28:25 +0000 (10:28 +0100)
committerWilly Tarreau <w@1wt.eu>
Thu, 12 Mar 2026 17:06:38 +0000 (18:06 +0100)
Most calls to mux ops were instrumented with a CALL_MUX_WITH_RET() or
CALL_MUX_NO_RET() macro in order to make the current thread's context
point to the called mux and be able to track its allocations. Only
a bunch of harmless mux_ctl() and ->subscribe/unsubscribe calls were
left untouched since useless. But destroy/detach/shut/init/snd_buf
and rcv_buf are now tracked.

It will not show allocations performed in IO callback via tasklet
wakeups however.

In order to ease reading of the output, cmp_memprof_ctx() knows about
muxes and sorts based on the .subscribe function address instead of
the mux_ops address so as to keep various callers grouped.

21 files changed:
include/haproxy/connection.h
include/haproxy/stconn.h
include/haproxy/tinfo-t.h
src/activity.c
src/backend.c
src/connection.c
src/haterm.c
src/mux_fcgi.c
src/mux_h1.c
src/mux_h2.c
src/mux_spop.c
src/proto_rhttp.c
src/quic_rx.c
src/quic_ssl.c
src/server.c
src/session.c
src/ssl_sock.c
src/stconn.c
src/tcpcheck.c
src/tools.c
src/xprt_handshake.c

index 7943ee39f866c8352d9c30bbafa5f0c492adb643..e311c8d129633188ae45e9c1bffe7ea2cc0f5609 100644 (file)
@@ -49,6 +49,13 @@ extern struct mux_stopping_data mux_stopping_data[MAX_THREADS];
 
 #define IS_HTX_CONN(conn) ((conn)->mux && ((conn)->mux->flags & MX_FL_HTX))
 
+/* macros to switch the calling context to the mux during a call. There's one
+ * with a return value for most calls, and one without for the few like shut(),
+ * detach() or destroy() with no return.
+ */
+#define CALL_MUX_WITH_RET(mux, func) EXEC_CTX_WITH_RET(EXEC_CTX_MAKE(TH_EX_CTX_MUX, (mux)), (mux)->func)
+#define CALL_MUX_NO_RET(mux, func)   EXEC_CTX_NO_RET(EXEC_CTX_MAKE(TH_EX_CTX_MUX, (mux)), (mux)->func)
+
 /* receive a PROXY protocol header over a connection */
 int conn_recv_proxy(struct connection *conn, int flag);
 int conn_send_proxy(struct connection *conn, unsigned int flag);
@@ -480,7 +487,7 @@ static inline int conn_install_mux(struct connection *conn, const struct mux_ops
 
        conn->mux = mux;
        conn->ctx = ctx;
-       ret = mux->init ? mux->init(conn, prx, sess, &BUF_NULL) : 0;
+       ret = mux->init ? CALL_MUX_WITH_RET(mux, init(conn, prx, sess, &BUF_NULL)) : 0;
        if (ret < 0) {
                conn->mux = NULL;
                conn->ctx = NULL;
index 23cb2e5e355bd22bfc7c73a6342bb16fdde87f55..c53c7223781be420cb1206277b7aeca039a070c8 100644 (file)
@@ -452,7 +452,7 @@ static inline size_t se_nego_ff(struct sedesc *se, struct buffer *input, size_t
                                goto end;
                        }
 
-                       ret = mux->nego_fastfwd(se->sc, input, count, flags);
+                       ret = CALL_MUX_WITH_RET(mux, nego_fastfwd(se->sc, input, count, flags));
                        if (se->iobuf.flags & IOBUF_FL_FF_BLOCKED) {
                                sc_ep_report_blocked_send(se->sc, 0);
 
@@ -485,7 +485,7 @@ static inline size_t se_done_ff(struct sedesc *se)
                size_t to_send = se_ff_data(se);
 
                BUG_ON(!mux->done_fastfwd);
-               ret = mux->done_fastfwd(se->sc);
+               ret = CALL_MUX_WITH_RET(mux, done_fastfwd(se->sc));
                if (ret) {
                        /* Something was forwarded, unblock the zero-copy forwarding.
                         * If all data was sent, report and send activity.
index e465fdedad7e9ba2e296ba0552c819713da79021..98b8762a8b31d4922002ab642a84a35c8eb4744f 100644 (file)
@@ -86,6 +86,7 @@ enum thread_exec_ctx_type {
        TH_EX_CTX_FUNC,                     /* hopefully recognizable function/callback, using .pointer */
        TH_EX_CTX_ACTION,                   /* directly registered action function, using .action_kwl */
        TH_EX_CTX_FLT,                      /* filter whose config is in .flt_conf */
+       TH_EX_CTX_MUX,                      /* mux whose mux_ops is in .mux_ops */
 };
 
 struct thread_exec_ctx {
@@ -99,6 +100,7 @@ struct thread_exec_ctx {
                const struct sample_conv_kw_list *conv_kwl;  /* used with TH_EX_CTX_CONV */
                const struct action_kw_list *action_kwl;  /* used with TH_EX_CTX_ACTION */
                const struct flt_conf *flt_conf;  /* used with TH_EX_CTX_FLTCONF */
+               const struct mux_ops *mux_ops;  /* used with TH_EX_CTX_MUX */
        };
 };
 
index 37a74f4bb862fc01bd83aaee73e173e9b65e770d..c6d8f1795d6f95bdef8323b16873f9bb675c3fa3 100644 (file)
@@ -964,10 +964,22 @@ static int cmp_memprof_ctx(const void *a, const void *b)
 {
        const struct memprof_stats *l = (const struct memprof_stats *)a;
        const struct memprof_stats *r = (const struct memprof_stats *)b;
+       const void *ptrl = l->exec_ctx.pointer;
+       const void *ptrr = r->exec_ctx.pointer;
 
-       if (l->exec_ctx.pointer > r->exec_ctx.pointer)
+       /* in case of a mux, we'll use the always-present ->subscribe()
+        * function as a sorting key so that mux-ops and other mux functions
+        * appear grouped together.
+        */
+       if (l->exec_ctx.type == TH_EX_CTX_MUX)
+               ptrl = l->exec_ctx.mux_ops->subscribe;
+
+       if (r->exec_ctx.type == TH_EX_CTX_MUX)
+               ptrr = r->exec_ctx.mux_ops->subscribe;
+
+       if (ptrl > ptrr)
                return -1;
-       else if (l->exec_ctx.pointer < r->exec_ctx.pointer)
+       else if (ptrl < ptrr)
                return 1;
        else if (l->exec_ctx.type > r->exec_ctx.type)
                return -1;
index 428036ddeff0a9396845f4abf4cdee9508741fe9..46eba155db8618f46eded069068522df7484acc2 100644 (file)
@@ -1396,7 +1396,7 @@ check_tgid:
                        tree = search_tree ? &srv->per_thr[i].safe_conns : &srv->per_thr[i].idle_conns;
                        conn = srv_lookup_conn(tree, hash);
                        while (conn) {
-                               if (conn->mux->takeover && conn->mux->takeover(conn, i, 0) == 0) {
+                               if (conn->mux->takeover && CALL_MUX_WITH_RET(conn->mux, takeover(conn, i, 0)) == 0) {
                                        conn_delete_from_tree(conn, i);
                                        _HA_ATOMIC_INC(&activity[tid].fd_takeover);
                                        found = 1;
@@ -1498,7 +1498,7 @@ takeover_random_idle_conn(struct ceb_root **root, int curtid)
 
        conn = ceb64_item_first(root, hash_node.node, hash_node.key, struct connection);
        while (conn) {
-               if (conn->mux->takeover && conn->mux->takeover(conn, curtid, 1) == 0) {
+               if (conn->mux->takeover && CALL_MUX_WITH_RET(conn->mux, takeover(conn, curtid, 1)) == 0) {
                        conn_delete_from_tree(conn, curtid);
                        return conn;
                }
@@ -1555,7 +1555,7 @@ kill_random_idle_conn(struct server *srv)
                         */
                        _HA_ATOMIC_INC(&srv->curr_used_conns);
                }
-               conn->mux->destroy(conn->ctx);
+               CALL_MUX_NO_RET(conn->mux, destroy(conn->ctx));
                return 1;
        }
        return 0;
@@ -1765,7 +1765,7 @@ int be_reuse_connection(int64_t hash, struct session *sess,
                        }
 
                        if (avail >= 1) {
-                               if (srv_conn->mux->attach(srv_conn, sc->sedesc, sess) == -1) {
+                               if (CALL_MUX_WITH_RET(srv_conn->mux, attach(srv_conn, sc->sedesc, sess)) == -1) {
                                        if (sc_reset_endp(sc) < 0)
                                                goto err;
                                        sc_ep_clr(sc, ~SE_FL_DETACHED);
@@ -1879,7 +1879,7 @@ int connect_server(struct stream *s)
                         * It will in turn call srv_release_conn through
                         * conn_free which also uses it.
                         */
-                       tokill_conn->mux->destroy(tokill_conn->ctx);
+                       CALL_MUX_NO_RET(tokill_conn->mux, destroy(tokill_conn->ctx));
                }
                else {
                        HA_SPIN_UNLOCK(IDLE_CONNS_LOCK, &idle_conns[tid].idle_conns_lock);
index 9986885d4f4f7d3cfca6023a38125d241fa83e57..227d25599a08e5101456661e77237b6beff8c5e6 100644 (file)
@@ -232,14 +232,14 @@ int conn_notify_mux(struct connection *conn, int old_flags, int forced_wake)
                        HA_SPIN_UNLOCK(IDLE_CONNS_LOCK, &idle_conns[tid].idle_conns_lock);
                }
 
-               ret = conn->mux->wake(conn);
+               ret = CALL_MUX_WITH_RET(conn->mux, wake(conn));
                if (ret < 0)
                        goto done;
 
                if (conn_in_list) {
                        if (srv && (srv->cur_admin & SRV_ADMF_MAINT)) {
                                /* Do not store an idle conn if server in maintenance. */
-                               conn->mux->destroy(conn->ctx);
+                               CALL_MUX_NO_RET(conn->mux, destroy(conn->ctx));
                                ret = -1;
                                goto done;
                        }
@@ -247,7 +247,7 @@ int conn_notify_mux(struct connection *conn, int old_flags, int forced_wake)
                        if (conn->flags & CO_FL_SESS_IDLE) {
                                if (!session_reinsert_idle_conn(conn->owner, conn)) {
                                        /* session add conn failure */
-                                       conn->mux->destroy(conn->ctx);
+                                       CALL_MUX_NO_RET(conn->mux, destroy(conn->ctx));
                                        ret = -1;
                                }
                        }
@@ -291,7 +291,7 @@ int conn_upgrade_mux_fe(struct connection *conn, void *ctx, struct buffer *buf,
        old_mux_ctx = conn->ctx;
        conn->mux = new_mux;
        conn->ctx = ctx;
-       if (new_mux->init(conn, bind_conf->frontend, conn->owner, buf) == -1) {
+       if (CALL_MUX_WITH_RET(new_mux, init(conn, bind_conf->frontend, conn->owner, buf)) == -1) {
                /* The mux upgrade failed, so restore the old mux */
                conn->ctx = old_mux_ctx;
                conn->mux = old_mux;
@@ -300,7 +300,7 @@ int conn_upgrade_mux_fe(struct connection *conn, void *ctx, struct buffer *buf,
 
        /* The mux was upgraded, destroy the old one */
        *buf = BUF_NULL;
-       old_mux->destroy(old_mux_ctx);
+       CALL_MUX_NO_RET(old_mux, destroy(old_mux_ctx));
        return 0;
 }
 
@@ -658,7 +658,7 @@ void conn_free(struct connection *conn)
 void conn_release(struct connection *conn)
 {
        if (conn->mux) {
-               conn->mux->destroy(conn->ctx);
+               CALL_MUX_NO_RET(conn->mux, destroy(conn->ctx));
        }
        else {
                conn_stop_tracking(conn);
@@ -3034,7 +3034,7 @@ static struct task *mux_stopping_process(struct task *t, void *ctx, unsigned int
 
        list_for_each_entry_safe(conn, back, &mux_stopping_data[tid].list, stopping_list) {
                if (conn->mux && conn->mux->wake)
-                       conn->mux->wake(conn);
+                       CALL_MUX_NO_RET(conn->mux, wake(conn));
        }
 
        return t;
index 564bf2aeabb4dc8fd46845a5c0dd810e70214060..98100f83ed9cf4c88d65851c130b4698d5138719 100644 (file)
@@ -250,7 +250,7 @@ static int hstream_htx_buf_rcv(struct connection *conn, struct hstream *hs)
                htx_reset(htxbuf(&hs->req));
                max = (IS_HTX_SC(hs->sc) ?  htx_free_space(htxbuf(&hs->req)) : b_room(&hs->req));
                sc_ep_clr(hs->sc, SE_FL_WANT_ROOM);
-               read = conn->mux->rcv_buf(hs->sc, &hs->req, max, 0);
+               read = CALL_MUX_WITH_RET(conn->mux, rcv_buf(hs->sc, &hs->req, max, 0));
                cur_read += read;
                if (!htx_expect_more(htxbuf(&hs->req))) {
                    fin = 1;
@@ -313,7 +313,7 @@ static int hstream_htx_buf_snd(struct connection *conn, struct hstream *hs)
                goto out;
        }
 
-       nret = conn->mux->snd_buf(hs->sc, &hs->res, htxbuf(&hs->res)->data, 0);
+       nret = CALL_MUX_WITH_RET(conn->mux, snd_buf(hs->sc, &hs->res, htxbuf(&hs->res)->data, 0));
        if (nret <= 0) {
                if (hs->flags & HS_ST_CONN_ERROR ||
                    conn->flags & CO_FL_ERROR || sc_ep_test(sc, SE_FL_ERROR)) {
@@ -873,7 +873,7 @@ static struct task *process_hstream(struct task *t, void *context, unsigned int
  out:
        if (!hs->to_write && !hs->req_body && htx_is_empty(htxbuf(&hs->res))) {
                TRACE_DEVEL("shutting down stream", HS_EV_HSTRM_SEND, hs);
-               conn->mux->shut(hs->sc, SE_SHW_SILENT|SE_SHW_NORMAL, NULL);
+               CALL_MUX_NO_RET(conn->mux, shut(hs->sc, SE_SHW_SILENT|SE_SHW_NORMAL, NULL));
        }
 
        if (hs->flags & HS_ST_CONN_ERROR ||
index 2ca2c5ee93cde4b1112def1347b0d9f1708daf89..acb06a7637b3d890dc926eae6429f64e19acdd7c 100644 (file)
@@ -3736,7 +3736,7 @@ static void fcgi_detach(struct sedesc *sd)
                        if (eb_is_empty(&fconn->streams_by_id)) {
                                if (!fconn->conn->owner) {
                                        /* Session insertion above has failed and connection is idle, remove it. */
-                                       fconn->conn->mux->destroy(fconn);
+                                       CALL_MUX_NO_RET(fconn->conn->mux, destroy(fconn));
                                        TRACE_DEVEL("outgoing connection killed", FCGI_EV_STRM_END|FCGI_EV_FCONN_ERR);
                                        return;
                                }
@@ -3749,7 +3749,7 @@ static void fcgi_detach(struct sedesc *sd)
 
                                /* Ensure session can keep a new idle connection. */
                                if (session_check_idle_conn(sess, fconn->conn) != 0) {
-                                       fconn->conn->mux->destroy(fconn);
+                                       CALL_MUX_NO_RET(fconn->conn->mux, destroy(fconn));
                                        TRACE_DEVEL("outgoing connection killed", FCGI_EV_STRM_END|FCGI_EV_FCONN_ERR);
                                        return;
                                }
@@ -3780,7 +3780,7 @@ static void fcgi_detach(struct sedesc *sd)
 
                                if (!srv_add_to_idle_list(objt_server(fconn->conn->target), fconn->conn, 1)) {
                                        /* The server doesn't want it, let's kill the connection right away */
-                                       fconn->conn->mux->destroy(fconn);
+                                       CALL_MUX_NO_RET(fconn->conn->mux, destroy(fconn));
                                        TRACE_DEVEL("outgoing connection killed", FCGI_EV_STRM_END|FCGI_EV_FCONN_ERR);
                                        return;
                                }
index 4be01c8f797c53ffa20e426d634718a71e594d6f..47cdfff2aa34b3a4896d3f1eadec17a38449e6e9 100644 (file)
@@ -1197,7 +1197,7 @@ static int h1s_finish_detach(struct h1s *h1s)
                        if (!session_add_conn(sess, h1c->conn)) {
                                /* HTTP/1.1 conn is always idle after detach, can be removed if session insert failed. */
                                h1c->conn->owner = NULL;
-                               h1c->conn->mux->destroy(h1c);
+                               CALL_MUX_NO_RET(h1c->conn->mux, destroy(h1c));
                                goto released;
                        }
 
@@ -1213,7 +1213,7 @@ static int h1s_finish_detach(struct h1s *h1s)
                        /* Ensure session can keep a new idle connection. */
                        if (session_check_idle_conn(sess, h1c->conn)) {
                                TRACE_DEVEL("outgoing connection rejected", H1_EV_STRM_END|H1_EV_H1C_END, h1c->conn);
-                               h1c->conn->mux->destroy(h1c);
+                               CALL_MUX_NO_RET(h1c->conn->mux, destroy(h1c));
                                goto released;
                        }
 
@@ -1236,7 +1236,7 @@ static int h1s_finish_detach(struct h1s *h1s)
 
                        if (!srv_add_to_idle_list(objt_server(h1c->conn->target), h1c->conn, is_not_first)) {
                                /* The server doesn't want it, let's kill the connection right away */
-                               h1c->conn->mux->destroy(h1c);
+                               CALL_MUX_NO_RET(h1c->conn->mux, destroy(h1c));
                                TRACE_DEVEL("outgoing connection killed", H1_EV_STRM_END|H1_EV_H1C_END);
                                goto released;
                        }
index 89439a129c6a83549175a6baa2ccedf86e4eba58..bfb02aa1df8ec0cd68cae3986dc459c3bbf13ee3 100644 (file)
@@ -5672,7 +5672,7 @@ static void h2_detach(struct sedesc *sd)
                                if (eb_is_empty(&h2c->streams_by_id)) {
                                        if (!h2c->conn->owner) {
                                                /* Session insertion above has failed and connection is idle, remove it. */
-                                               h2c->conn->mux->destroy(h2c);
+                                               CALL_MUX_NO_RET(h2c->conn->mux, destroy(h2c));
                                                TRACE_DEVEL("leaving on error after killing outgoing connection", H2_EV_STRM_END|H2_EV_H2C_ERR);
                                                return;
                                        }
@@ -5685,7 +5685,7 @@ static void h2_detach(struct sedesc *sd)
 
                                        /* Ensure session can keep a new idle connection. */
                                        if (session_check_idle_conn(sess, h2c->conn) != 0) {
-                                               h2c->conn->mux->destroy(h2c);
+                                               CALL_MUX_NO_RET(h2c->conn->mux, destroy(h2c));
                                                TRACE_DEVEL("leaving without reusable idle connection", H2_EV_STRM_END);
                                                return;
                                        }
@@ -5716,7 +5716,7 @@ static void h2_detach(struct sedesc *sd)
 
                                        if (!srv_add_to_idle_list(objt_server(h2c->conn->target), h2c->conn, 1)) {
                                                /* The server doesn't want it, let's kill the connection right away */
-                                               h2c->conn->mux->destroy(h2c);
+                                               CALL_MUX_NO_RET(h2c->conn->mux, destroy(h2c));
                                                TRACE_DEVEL("leaving on error after killing outgoing connection", H2_EV_STRM_END|H2_EV_H2C_ERR);
                                                return;
                                        }
index 162842ab25f45f68727c8032a02ec28e519888da..e43f8d80af43121190f48719f08b02c44761503d 100644 (file)
@@ -3013,7 +3013,7 @@ static void spop_detach(struct sedesc *sd)
                        if (eb_is_empty(&spop_conn->streams_by_id)) {
                                if (!spop_conn->conn->owner) {
                                        /* Session insertion above has failed and connection is idle, remove it. */
-                                       spop_conn->conn->mux->destroy(spop_conn);
+                                       CALL_MUX_NO_RET(spop_conn->conn->mux, destroy(spop_conn));
                                        TRACE_DEVEL("leaving on error after killing outgoing connection", SPOP_EV_STRM_END|SPOP_EV_SPOP_CONN_ERR);
                                        return;
                                }
@@ -3026,7 +3026,7 @@ static void spop_detach(struct sedesc *sd)
 
                                /* Ensure session can keep a new idle connection. */
                                if (session_check_idle_conn(sess, spop_conn->conn) != 0) {
-                                       spop_conn->conn->mux->destroy(spop_conn);
+                                       CALL_MUX_NO_RET(spop_conn->conn->mux, destroy(spop_conn));
                                        TRACE_DEVEL("leaving without reusable idle connection", SPOP_EV_STRM_END);
                                        return;
                                }
@@ -3057,7 +3057,7 @@ static void spop_detach(struct sedesc *sd)
 
                                if (!srv_add_to_idle_list(objt_server(spop_conn->conn->target), spop_conn->conn, 1)) {
                                        /* The server doesn't want it, let's kill the connection right away */
-                                       spop_conn->conn->mux->destroy(spop_conn);
+                                       CALL_MUX_NO_RET(spop_conn->conn->mux, destroy(spop_conn));
                                        TRACE_DEVEL("leaving on error after killing outgoing connection", SPOP_EV_STRM_END|SPOP_EV_SPOP_CONN_ERR);
                                        return;
                                }
index f94b4a67e6a213f1f3904eed7282189b62f3f7e8..515dee39dbd218f91b2ba4fa5f2d48331f535954 100644 (file)
@@ -241,7 +241,7 @@ struct task *rhttp_process(struct task *task, void *ctx, unsigned int state)
                         * directly.
                         */
                        if (conn->mux && conn->mux->destroy) {
-                               conn->mux->destroy(conn->ctx);
+                               CALL_MUX_NO_RET(conn->mux, destroy(conn->ctx));
                        }
                        else {
                                conn_stop_tracking(conn);
@@ -464,7 +464,7 @@ struct connection *rhttp_accept_conn(struct listener *l, int *status)
        BUG_ON(!(conn->flags & CO_FL_ACT_REVERSING));
        conn->flags &= ~CO_FL_ACT_REVERSING;
        conn->flags |= CO_FL_REVERSED;
-       conn->mux->ctl(conn, MUX_CTL_REVERSE_CONN, NULL);
+       CALL_MUX_NO_RET(conn->mux, ctl(conn, MUX_CTL_REVERSE_CONN, NULL));
 
        l->rx.rhttp.pend_conn = NULL;
        *status = CO_AC_NONE;
index 54a6991628681c3c41f17411854c90394a1b2092..0e2deb021dc28ed2ca487c063a8f877d9cff740b 100644 (file)
@@ -1105,7 +1105,7 @@ static int qc_parse_pkt_frms(struct quic_conn *qc, struct quic_rx_packet *pkt,
                                if (objt_server(qc->conn->target) && !qc->conn->mux) {
                                        /* This has as side effect to close the connection stream */
                                        if (conn_create_mux(qc->conn, NULL) >= 0)
-                                               qc->conn->mux->wake(qc->conn);
+                                               CALL_MUX_NO_RET(qc->conn->mux, wake(qc->conn));
                                }
                        }
                        __fallthrough;
index 710fef4e49fed952e3979c6354d127fc9c497b54..b24d9b11baf386a724ac728e65b7eb72e94863c4 100644 (file)
@@ -180,7 +180,7 @@ static int ha_quic_send_alert(SSL *ssl, enum ssl_encryption_level_t level, uint8
                if (objt_server(qc->conn->target) && !qc->conn->mux) {
                        /* This has as side effect to close the connection stream */
                        if (conn_create_mux(qc->conn, NULL) >= 0)
-                               qc->conn->mux->wake(qc->conn);
+                               CALL_MUX_NO_RET(qc->conn->mux, wake(qc->conn));
                }
        }
 
@@ -1029,7 +1029,7 @@ int qc_ssl_do_hanshake(struct quic_conn *qc, struct ssl_sock_ctx *ctx)
                                }
 
                                /* Wake up MUX after its creation. Operation similar to TLS+ALPN on TCP stack. */
-                               qc->conn->mux->wake(qc->conn);
+                               CALL_MUX_NO_RET(qc->conn->mux, wake(qc->conn));
                        }
                        else {
                                /* Wake up upper layer if the MUX is already initialized.
index b7ea4a51550ad45308c14d29c35bf2f1c79bef88..a418b7358ada4e7d3fb9bf5f1b5e576eb088b348 100644 (file)
@@ -7247,7 +7247,7 @@ struct task *srv_cleanup_toremove_conns(struct task *task, void *context, unsign
 
        while ((conn = MT_LIST_POP(&idle_conns[tid].toremove_conns,
                                       struct connection *, toremove_list)) != NULL) {
-               conn->mux->destroy(conn->ctx);
+               CALL_MUX_NO_RET(conn->mux, destroy(conn->ctx));
        }
 
        return task;
index 4cef01b67e5870493ebe3880f2db93f2e4c63dd2..9d4c6139aafc001294373083f10626580798a23d 100644 (file)
@@ -138,7 +138,7 @@ void session_free(struct session *sess)
        vars_prune_per_sess(&sess->vars);
        conn = objt_conn(sess->origin);
        if (conn != NULL && conn->mux)
-               conn->mux->destroy(conn->ctx);
+               CALL_MUX_NO_RET(conn->mux, destroy(conn->ctx));
 
        HA_SPIN_LOCK(IDLE_CONNS_LOCK, &idle_conns[tid].idle_conns_lock);
        list_for_each_entry_safe(pconns, pconns_back, &sess->priv_conns, sess_el) {
index 894e8293a4f06c5e488f62072dfb69e66d05e85f..2b1daa748fc1342020825488494f0acb3a51db75 100644 (file)
@@ -6960,7 +6960,7 @@ struct task *ssl_sock_io_cb(struct task *t, void *context, unsigned int state)
                        if (!ctx->conn->mux)
                                ret = conn_create_mux(ctx->conn, &closed_connection);
                        if (ret >= 0 && !woke && ctx->conn->mux && ctx->conn->mux->wake) {
-                               ret = ctx->conn->mux->wake(ctx->conn);
+                               ret = CALL_MUX_WITH_RET(ctx->conn->mux, wake(ctx->conn));
                                if (ret < 0)
                                        closed_connection = 1;
                        }
@@ -6991,7 +6991,7 @@ leave:
                                TRACE_DEVEL("adding conn back to session list", SSL_EV_CONN_IO_CB, conn);
                                if (!session_reinsert_idle_conn(conn->owner, conn)) {
                                        /* session add conn failure */
-                                       conn->mux->destroy(conn->ctx);
+                                       CALL_MUX_NO_RET(conn->mux, destroy(conn->ctx));
                                        t = NULL;
                                }
                        }
@@ -7003,7 +7003,7 @@ leave:
                }
                else {
                        /* Do not store an idle conn if server in maintenance. */
-                       conn->mux->destroy(conn->ctx);
+                       CALL_MUX_NO_RET(conn->mux, destroy(conn->ctx));
                        t = NULL;
                }
        }
index 6c959d51503a0348e073fc9f8f042e6c196183f2..82c7ed8f2c120f22b368605acc2af6f3b53fb36a 100644 (file)
@@ -106,7 +106,7 @@ void se_shutdown(struct sedesc *sedesc, enum se_shut_mode mode)
                                sdo = se_opposite(sedesc);
                                if (sdo)
                                        reason = &sdo->abort_info;
-                               mux->shut(sedesc->sc, mode, reason);
+                               CALL_MUX_NO_RET(mux, shut(sedesc->sc, mode, reason));
                        }
                        se_fl_set(sedesc, flags);
                }
@@ -393,7 +393,7 @@ static void sc_detach_endp(struct stconn **scp)
                        se_fl_set(sedesc, SE_FL_ORPHAN);
                        sedesc->sc = NULL;
                        sc->sedesc = NULL;
-                       conn->mux->detach(sedesc);
+                       CALL_MUX_NO_RET(conn->mux, detach(sedesc));
                }
                else {
                        /* It's too early to have a mux, let's just destroy
@@ -1118,7 +1118,7 @@ int sc_conn_recv(struct stconn *sc)
                        goto abort_fastfwd;
                }
                sc_ep_fwd_kip(sc, sc_opposite(sc));
-               ret = conn->mux->fastfwd(sc, ic->to_forward, flags);
+               ret = CALL_MUX_WITH_RET(conn->mux, fastfwd(sc, ic->to_forward, flags));
                if (ret < 0)
                        goto abort_fastfwd;
                else if (ret > 0) {
@@ -1189,7 +1189,7 @@ int sc_conn_recv(struct stconn *sc)
                 * SE_FL_RCV_MORE on the SC if more space is needed.
                 */
                max = channel_recv_max(ic);
-               ret = conn->mux->rcv_buf(sc, &ic->buf, max, cur_flags);
+               ret = CALL_MUX_WITH_RET(conn->mux, rcv_buf(sc, &ic->buf, max, cur_flags));
 
                if (sc_ep_test(sc, SE_FL_WANT_ROOM)) {
                        /* SE_FL_WANT_ROOM must not be reported if the channel's
@@ -1437,7 +1437,7 @@ int sc_conn_send(struct stconn *sc)
                if (oc->flags & CF_STREAMER)
                        send_flag |= CO_SFL_STREAMER;
 
-               ret = conn->mux->resume_fastfwd(sc, send_flag);
+               ret = CALL_MUX_WITH_RET(conn->mux, resume_fastfwd(sc, send_flag));
                if (ret > 0) {
                        sc->bytes_out += ret;
                        did_send = 1;
@@ -1509,7 +1509,7 @@ int sc_conn_send(struct stconn *sc)
                if ((sc->flags & SC_FL_SHUT_WANTED) && co_data(oc) == c_data(oc))
                        send_flag |= CO_SFL_LAST_DATA;
 
-               ret = conn->mux->snd_buf(sc, &oc->buf, co_data(oc), send_flag);
+               ret = CALL_MUX_WITH_RET(conn->mux, snd_buf(sc, &oc->buf, co_data(oc), send_flag));
                if (ret > 0) {
                        did_send = 1;
                        c_rew(oc, ret);
index 362673ddd1678262f04036a06399fd240223c156..fe8d4f76635d1eef6a7bb3c7d620bd54520ca322 100644 (file)
@@ -1810,8 +1810,8 @@ enum tcpcheck_eval_ret tcpcheck_eval_send(struct check *check, struct tcpcheck_r
 
   do_send:
        TRACE_DATA("send data", CHK_EV_TCPCHK_SND|CHK_EV_TX_DATA, check);
-       if (conn->mux->snd_buf(sc, &check->bo,
-                              (IS_HTX_CONN(conn) ? (htxbuf(&check->bo))->data: b_data(&check->bo)), 0) <= 0) {
+       if (CALL_MUX_WITH_RET(conn->mux, snd_buf(sc, &check->bo,
+                             (IS_HTX_CONN(conn) ? (htxbuf(&check->bo))->data: b_data(&check->bo)), 0)) <= 0) {
                if ((conn->flags & CO_FL_ERROR) || sc_ep_test(sc, SE_FL_ERROR)) {
                        ret = TCPCHK_EVAL_STOP;
                        TRACE_DEVEL("connection error during send", CHK_EV_TCPCHK_SND|CHK_EV_TX_DATA|CHK_EV_TX_ERR, check);
@@ -1898,7 +1898,7 @@ enum tcpcheck_eval_ret tcpcheck_eval_recv(struct check *check, struct tcpcheck_r
        while (sc_ep_test(sc, SE_FL_RCV_MORE) ||
               (!(conn->flags & CO_FL_ERROR) && !sc_ep_test(sc, SE_FL_ERROR | SE_FL_EOS))) {
                max = (IS_HTX_SC(sc) ?  htx_free_space(htxbuf(&check->bi)) : b_room(&check->bi));
-               read = conn->mux->rcv_buf(sc, &check->bi, max, 0);
+               read = CALL_MUX_WITH_RET(conn->mux, rcv_buf(sc, &check->bi, max, 0));
                cur_read += read;
                if (!read ||
                    sc_ep_test(sc, SE_FL_WANT_ROOM) ||
index bbacf8f38999824a08bd699f01a6fdf4375cd7f5..16796afcd700a6cd5e3d99dd4f8c4b1e870c35aa 100644 (file)
@@ -7545,6 +7545,9 @@ void chunk_append_thread_ctx(struct buffer *output, const struct thread_exec_ctx
        case TH_EX_CTX_FLT:
                chunk_appendf(output,"flt '%s'", ctx->flt_conf->id);
                break;
+       case TH_EX_CTX_MUX:
+               chunk_appendf(output,"mux '%s'", ctx->mux_ops->name);
+               break;
        default:
                chunk_appendf(output,"other ctx %p", ctx->pointer);
                break;
index 9e81aa4a4ad25c3981dedee442a1d37778864616..4f09fc1cd6b200dc73582b7b8458e652748f872f 100644 (file)
@@ -117,7 +117,7 @@ out:
                        if (!ctx->conn->mux)
                                ret = conn_create_mux(ctx->conn, NULL);
                        if (ret >= 0 && !woke && ctx->conn->mux && ctx->conn->mux->wake)
-                               ret = ctx->conn->mux->wake(ctx->conn);
+                               ret = CALL_MUX_WITH_RET(ctx->conn->mux, wake(ctx->conn));
                }
                tasklet_free(ctx->wait_event.tasklet);
                pool_free(xprt_handshake_ctx_pool, ctx);