MEDIUM: mux-h1: Use a h1c flag to block reads when splicing is in-progress

Instead of using 2 flags on the H1 stream (H1S_F_BUF_FLUSH and
H1S_F_SPLICED_DATA), we now only use one flag on the H1 connection
(H1C_F_WANT_SPLICE) to notify we want to use splicing or we are using
splicing. This flag blocks the calls to rcv_buf() connection callback.

It is a bit easier to set the H1 connection capability to receive data in
its input buffer instead of relying on the H1 stream.
diff --git a/src/mux_h1.c b/src/mux_h1.c
index ee67883..6d48813 100644
--- a/src/mux_h1.c
+++ b/src/mux_h1.c
@@ -57,6 +57,7 @@
 #define H1C_F_CO_STREAMER    0x00080000 /* set if CO_SFL_STREAMER must be set when calling xprt->snd_buf() */
 
 #define H1C_F_WAIT_OPPOSITE  0x00100000 /* Don't read more data for now, waiting sync with opposite side */
+#define H1C_F_WANT_SPLICE    0x00200000 /* Don't read into a bufffer because we want to use or we are using splicing */
 /*
  * H1 Stream flags (32 bits)
  */
@@ -70,8 +71,6 @@
 #define H1S_F_WANT_CLO       0x00000040
 #define H1S_F_WANT_MSK       0x00000070
 #define H1S_F_NOT_FIRST      0x00000080 /* The H1 stream is not the first one */
-#define H1S_F_BUF_FLUSH      0x00000100 /* Flush input buffer and don't read more data */
-#define H1S_F_SPLICED_DATA   0x00000200 /* Set when the kernel splicing is in used */
 #define H1S_F_PARSING_DONE   0x00000400 /* Set when incoming message parsing is finished (EOM added) */
 /* 0x00000800 .. 0x00001000 unused */
 #define H1S_F_HAVE_SRV_NAME  0x00002000 /* Set during output process if the server name header was added to the request */
@@ -2023,8 +2022,8 @@
 		return (b_data(&h1c->ibuf));
 	}
 
-	if (!h1_recv_allowed(h1c)) {
-		TRACE_DEVEL("leaving on !recv_allowed", H1_EV_H1C_RECV, h1c->conn);
+	if ((h1c->flags & H1C_F_WANT_SPLICE) || !h1_recv_allowed(h1c)) {
+		TRACE_DEVEL("leaving on (want_splice|!recv_allowed)", H1_EV_H1C_RECV, h1c->conn);
 		rcvd = 1;
 		goto end;
 	}
@@ -2035,14 +2034,6 @@
 		goto end;
 	}
 
-	if (h1s && (h1s->flags & (H1S_F_BUF_FLUSH|H1S_F_SPLICED_DATA))) {
-		if (!h1s_data_pending(h1s))
-			h1_wake_stream_for_recv(h1s);
-		rcvd = 1;
-		TRACE_DEVEL("leaving on (buf_flush|spliced_data)", H1_EV_H1C_RECV, h1c->conn);
-		goto end;
-	}
-
 	/*
 	 * If we only have a small amount of data, realign it,
 	 * it's probably cheaper than doing 2 recv() calls.
@@ -2201,6 +2192,11 @@
 		h1s = h1c->h1s;
 	}
 
+	if ((h1c->flags & H1C_F_WANT_SPLICE) && !h1s_data_pending(h1s)) {
+		TRACE_DEVEL("xprt rcv_buf blocked (want_splice), notify h1s for recv", H1_EV_H1C_RECV, h1c->conn);
+		h1_wake_stream_for_recv(h1s);
+	}
+
 	if (b_data(&h1c->ibuf) && h1s->sess->t_idle == -1)
 		h1s->sess->t_idle = tv_ms_elapsed(&h1s->sess->tv_accept, &now) - h1s->sess->t_handshake;
 
@@ -2690,15 +2686,11 @@
 
 	if (flags & CO_RFL_BUF_FLUSH) {
 		if (h1m->state == H1_MSG_TUNNEL || (h1m->state == H1_MSG_DATA && h1m->curr_len)) {
-			h1s->flags |= H1S_F_BUF_FLUSH;
-			TRACE_STATE("flush stream's buffer", H1_EV_STRM_RECV, h1c->conn, h1s);
+			h1c->flags |= H1C_F_WANT_SPLICE;
+			TRACE_STATE("Block xprt rcv_buf to flush stream's buffer (want_splice)", H1_EV_STRM_RECV, h1c->conn, h1s);
 		}
 	}
 	else {
-		if (ret && h1s->flags & H1S_F_SPLICED_DATA) {
-			h1s->flags &= ~H1S_F_SPLICED_DATA;
-			TRACE_STATE("disable splicing", H1_EV_STRM_RECV, h1c->conn, h1s);
-		}
 		if (h1m->state != H1_MSG_DONE && !(h1c->wait_event.events & SUB_RETRY_RECV))
 			h1c->conn->xprt->subscribe(h1c->conn, h1c->conn->xprt_ctx, SUB_RETRY_RECV, &h1c->wait_event);
 	}
@@ -2770,8 +2762,8 @@
 	TRACE_ENTER(H1_EV_STRM_RECV, cs->conn, h1s, 0, (size_t[]){count});
 
 	if ((h1m->flags & H1_MF_CHNK) || (h1m->state != H1_MSG_DATA && h1m->state != H1_MSG_TUNNEL)) {
-		h1s->flags &= ~(H1S_F_BUF_FLUSH|H1S_F_SPLICED_DATA);
-		TRACE_STATE("disable splicing on !(msg_data|msg_tunnel)", H1_EV_STRM_RECV, cs->conn, h1s);
+		h1s->h1c->flags &= ~H1C_F_WANT_SPLICE;
+		TRACE_STATE("Allow xprt rcv_buf on !(msg_data|msg_tunnel)", H1_EV_STRM_RECV, cs->conn, h1s);
 		if (!(h1s->h1c->wait_event.events & SUB_RETRY_RECV)) {
 			TRACE_STATE("restart receiving data, subscribing", H1_EV_STRM_RECV, cs->conn, h1s);
 			cs->conn->xprt->subscribe(cs->conn, cs->conn->xprt_ctx, SUB_RETRY_RECV, &h1s->h1c->wait_event);
@@ -2779,18 +2771,15 @@
 		goto end;
 	}
 
+	if (!(h1s->h1c->flags & H1C_F_WANT_SPLICE)) {
+		h1s->h1c->flags |= H1C_F_WANT_SPLICE;
+		TRACE_STATE("Block xprt rcv_buf to perform splicing", H1_EV_STRM_RECV, cs->conn, h1s);
+	}
 	if (h1s_data_pending(h1s)) {
-		h1s->flags |= H1S_F_BUF_FLUSH;
 		TRACE_STATE("flush input buffer before splicing", H1_EV_STRM_RECV, cs->conn, h1s);
 		goto end;
 	}
 
-	if (!(h1s->flags & H1S_F_SPLICED_DATA)) {
-		h1s->flags &= ~H1S_F_BUF_FLUSH;
-		h1s->flags |= H1S_F_SPLICED_DATA;
-		TRACE_STATE("enable splicing", H1_EV_STRM_RECV, cs->conn, h1s);
-	}
-
 	if (!h1_recv_allowed(h1s->h1c)) {
 		TRACE_DEVEL("leaving on !recv_allowed", H1_EV_STRM_RECV, cs->conn, h1s);
 		goto end;
@@ -2802,16 +2791,16 @@
 	if (h1m->state == H1_MSG_DATA && ret >= 0) {
 		h1m->curr_len -= ret;
 		if (!h1m->curr_len) {
-			h1s->flags &= ~(H1S_F_BUF_FLUSH|H1S_F_SPLICED_DATA);
-			TRACE_STATE("disable splicing on !curr_len", H1_EV_STRM_RECV, cs->conn, h1s);
+			h1s->h1c->flags &= ~H1C_F_WANT_SPLICE;
+			TRACE_STATE("Allow xprt rcv_buf on !curr_len", H1_EV_STRM_RECV, cs->conn, h1s);
 		}
 	}
 
   end:
 	if (conn_xprt_read0_pending(cs->conn)) {
 		h1s->flags |= H1S_F_REOS;
-		h1s->flags &= ~(H1S_F_BUF_FLUSH|H1S_F_SPLICED_DATA);
-		TRACE_STATE("read0 on connection", H1_EV_STRM_RECV, cs->conn, h1s);
+		h1s->h1c->flags &= ~H1C_F_WANT_SPLICE;
+		TRACE_STATE("Allow xprt rcv_buf on read0", H1_EV_STRM_RECV, cs->conn, h1s);
 	}
 
 	if ((h1s->flags & H1S_F_REOS) ||