From deccd1116db31d64e864a60f0b1a9d0ce017ee1d Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Thu, 14 Jun 2018 18:38:55 +0200 Subject: [PATCH] MEDIUM: mux: make mux->snd_buf() take the byte count in argument This way the mux doesn't need to modify the buffer's metadata anymore nor to know the output's size. The mux->snd_buf() function now takes a const buffer and it's up to the caller to update the buffer's state. The return type was updated to return a size_t to comply with the count argument. --- include/types/connection.h | 2 +- src/checks.c | 11 +++++++++-- src/mux_h2.c | 4 +--- src/mux_pt.c | 10 ++-------- src/stream_interface.c | 7 +++++-- 5 files changed, 18 insertions(+), 16 deletions(-) diff --git a/include/types/connection.h b/include/types/connection.h index 6cd8a3a2d3..f9757e5473 100644 --- a/include/types/connection.h +++ b/include/types/connection.h @@ -298,7 +298,7 @@ struct mux_ops { int (*wake)(struct connection *conn); /* mux-layer callback to report activity, mandatory */ void (*update_poll)(struct conn_stream *cs); /* commit cs flags to mux/conn */ int (*rcv_buf)(struct conn_stream *cs, struct buffer *buf, int count); /* Called from the upper layer to get data */ - int (*snd_buf)(struct conn_stream *cs, struct buffer *buf, int flags); /* Called from the upper layer to send data */ + size_t (*snd_buf)(struct conn_stream *cs, const struct buffer *buf, size_t count, int flags); /* Called from the upper layer to send data */ int (*rcv_pipe)(struct conn_stream *cs, struct pipe *pipe, unsigned int count); /* recv-to-pipe callback */ int (*snd_pipe)(struct conn_stream *cs, struct pipe *pipe); /* send-to-pipe callback */ void (*shutr)(struct conn_stream *cs, enum cs_shr_mode); /* shutr function */ diff --git a/src/checks.c b/src/checks.c index 0150bbb7ee..9cbc5de58d 100644 --- a/src/checks.c +++ b/src/checks.c @@ -746,7 +746,9 @@ static void event_srv_chk_w(struct conn_stream *cs) goto out_unlock; if (check->bo->o) { - conn->mux->snd_buf(cs, check->bo, 0); + b_del(check->bo, conn->mux->snd_buf(cs, check->bo, check->bo->o, 0)); + b_realign_if_empty(check->bo); + if (conn->flags & CO_FL_ERROR || cs->flags & CS_FL_ERROR) { chk_report_conn_err(check, errno, 0); __cs_stop_both(cs); @@ -2669,9 +2671,14 @@ static int tcpcheck_main(struct check *check) (&check->current_step->list == head || check->current_step->action != TCPCHK_ACT_SEND || check->current_step->string_len >= buffer_total_space(check->bo))) { + int ret; __cs_want_send(cs); - if (conn->mux->snd_buf(cs, check->bo, 0) <= 0) { + ret = conn->mux->snd_buf(cs, check->bo, check->bo->o, 0); + b_del(check->bo, ret); + b_realign_if_empty(check->bo); + + if (ret <= 0) { if (conn->flags & CO_FL_ERROR || cs->flags & CS_FL_ERROR) { chk_report_conn_err(check, errno, 0); __cs_stop_both(cs); diff --git a/src/mux_h2.c b/src/mux_h2.c index 2251a8e046..4a39b51044 100644 --- a/src/mux_h2.c +++ b/src/mux_h2.c @@ -3378,10 +3378,9 @@ static size_t h2s_frt_make_resp_data(struct h2s *h2s, const struct buffer *buf, } /* Called from the upper layer, to send data */ -static int h2_snd_buf(struct conn_stream *cs, struct buffer *buf, int flags) +static size_t h2_snd_buf(struct conn_stream *cs, const struct buffer *buf, size_t count, int flags) { struct h2s *h2s = cs->ctx; - size_t count = buf->o; size_t total = 0; size_t ret; @@ -3452,7 +3451,6 @@ static int h2_snd_buf(struct conn_stream *cs, struct buffer *buf, int flags) LIST_ADDQ(&h2s->h2c->send_list, &h2s->list); } - b_del(buf, total); return total; } diff --git a/src/mux_pt.c b/src/mux_pt.c index 688b7d8fab..d65c4e2024 100644 --- a/src/mux_pt.c +++ b/src/mux_pt.c @@ -172,15 +172,9 @@ static int mux_pt_rcv_buf(struct conn_stream *cs, struct buffer *buf, int count) } /* Called from the upper layer, to send data */ -static int mux_pt_snd_buf(struct conn_stream *cs, struct buffer *buf, int flags) +static size_t mux_pt_snd_buf(struct conn_stream *cs, const struct buffer *buf, size_t count, int flags) { - int ret = cs->conn->xprt->snd_buf(cs->conn, buf, buf->o, flags); - - if (ret > 0) - b_del(buf, ret); - - b_realign_if_empty(buf); - return ret; + return cs->conn->xprt->snd_buf(cs->conn, buf, count, flags); } #if defined(CONFIG_HAP_LINUX_SPLICE) diff --git a/src/stream_interface.c b/src/stream_interface.c index 62cbf71f3e..4a095d8dae 100644 --- a/src/stream_interface.c +++ b/src/stream_interface.c @@ -683,11 +683,14 @@ static void si_cs_send(struct conn_stream *cs) if (oc->flags & CF_STREAMER) send_flag |= CO_SFL_STREAMER; - ret = conn->mux->snd_buf(cs, oc->buf, send_flag); + ret = conn->mux->snd_buf(cs, oc->buf, co_data(oc), send_flag); if (ret > 0) { oc->flags |= CF_WRITE_PARTIAL | CF_WROTE_DATA | CF_WRITE_EVENT; - if (!oc->buf->o) { + b_del(oc->buf, ret); + c_realign_if_empty(oc); + + if (!co_data(oc)) { /* Always clear both flags once everything has been sent, they're one-shot */ oc->flags &= ~(CF_EXPECT_MORE | CF_SEND_DONTWAIT); } -- 2.39.5