MINOR: stream-int: Notify mux when the buffer is not stuck when calling rcv_buf
The transient flag CO_RFL_BUF_NOT_STUCK should now be set when the mux's
rcv_buf() function is called, in si_cs_recv(), to be sure the mux is able to
perform some optimisation during data copy. This flag is set when we are
sure the channel buffer is not stuck. Concretely, it happens when there are
data scheduled to be sent.
It is not a fix and this flag is not used for now. But it makes sense to have
this info to be sure to be able to do some optimisations if necessary.
This patch is related to the issue #1362. It may be backported to 2.4 to
ease future backports.
(cherry picked from commit 564e39c4c602a7ec0196e257732957bbfc3cbcae)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
diff --git a/src/mux_fcgi.c b/src/mux_fcgi.c
index 7281b43..bc25d5f 100644
--- a/src/mux_fcgi.c
+++ b/src/mux_fcgi.c
@@ -3909,7 +3909,18 @@
return 0;
}
-/* Called from the upper layer, to receive data */
+/* Called from the upper layer, to receive data
+ *
+ * The caller is responsible for defragmenting <buf> if necessary. But <flags>
+ * must be tested to know the calling context. If CO_RFL_BUF_FLUSH is set, it
+ * means the caller wants to flush input data (from the mux buffer and the
+ * channel buffer) to be able to use kernel splicing or any kind of mux-to-mux
+ * xfer. If CO_RFL_KEEP_RECV is set, the mux must always subscribe for read
+ * events before giving back. CO_RFL_BUF_WET is set if <buf> is congested with
+ * data scheduled for leaving soon. CO_RFL_BUF_NOT_STUCK is set to instruct the
+ * mux it may optimize the data copy to <buf> if necessary. Otherwise, it should
+ * copy as much data as possible.
+ */
static size_t fcgi_rcv_buf(struct conn_stream *cs, struct buffer *buf, size_t count, int flags)
{
struct fcgi_strm *fstrm = cs->ctx;
diff --git a/src/mux_h1.c b/src/mux_h1.c
index ee63b3e..6177fbc 100644
--- a/src/mux_h1.c
+++ b/src/mux_h1.c
@@ -3337,7 +3337,18 @@
return 0;
}
-/* Called from the upper layer, to receive data */
+/* Called from the upper layer, to receive data.
+ *
+ * The caller is responsible for defragmenting <buf> if necessary. But <flags>
+ * must be tested to know the calling context. If CO_RFL_BUF_FLUSH is set, it
+ * means the caller wants to flush input data (from the mux buffer and the
+ * channel buffer) to be able to use kernel splicing or any kind of mux-to-mux
+ * xfer. If CO_RFL_KEEP_RECV is set, the mux must always subscribe for read
+ * events before giving back. CO_RFL_BUF_WET is set if <buf> is congested with
+ * data scheduled for leaving soon. CO_RFL_BUF_NOT_STUCK is set to instruct the
+ * mux it may optimize the data copy to <buf> if necessary. Otherwise, it should
+ * copy as much data as possible.
+ */
static size_t h1_rcv_buf(struct conn_stream *cs, struct buffer *buf, size_t count, int flags)
{
struct h1s *h1s = cs->ctx;
diff --git a/src/mux_h2.c b/src/mux_h2.c
index 45506c6..dfe0b37 100644
--- a/src/mux_h2.c
+++ b/src/mux_h2.c
@@ -6255,7 +6255,18 @@
}
-/* Called from the upper layer, to receive data */
+/* Called from the upper layer, to receive data
+ *
+ * The caller is responsible for defragmenting <buf> if necessary. But <flags>
+ * must be tested to know the calling context. If CO_RFL_BUF_FLUSH is set, it
+ * means the caller wants to flush input data (from the mux buffer and the
+ * channel buffer) to be able to use kernel splicing or any kind of mux-to-mux
+ * xfer. If CO_RFL_KEEP_RECV is set, the mux must always subscribe for read
+ * events before giving back. CO_RFL_BUF_WET is set if <buf> is congested with
+ * data scheduled for leaving soon. CO_RFL_BUF_NOT_STUCK is set to instruct the
+ * mux it may optimize the data copy to <buf> if necessary. Otherwise, it should
+ * copy as much data as possible.
+ */
static size_t h2_rcv_buf(struct conn_stream *cs, struct buffer *buf, size_t count, int flags)
{
struct h2s *h2s = cs->ctx;
diff --git a/src/mux_pt.c b/src/mux_pt.c
index 86b86e2..713f110 100644
--- a/src/mux_pt.c
+++ b/src/mux_pt.c
@@ -484,6 +484,16 @@
/*
* Called from the upper layer, to get more data
+ *
+ * The caller is responsible for defragmenting <buf> if necessary. But <flags>
+ * must be tested to know the calling context. If CO_RFL_BUF_FLUSH is set, it
+ * means the caller wants to flush input data (from the mux buffer and the
+ * channel buffer) to be able to use kernel splicing or any kind of mux-to-mux
+ * xfer. If CO_RFL_KEEP_RECV is set, the mux must always subscribe for read
+ * events before giving back. CO_RFL_BUF_WET is set if <buf> is congested with
+ * data scheduled for leaving soon. CO_RFL_BUF_NOT_STUCK is set to instruct the
+ * mux it may optimize the data copy to <buf> if necessary. Otherwise, it should
+ * copy as much data as possible.
*/
static size_t mux_pt_rcv_buf(struct conn_stream *cs, struct buffer *buf, size_t count, int flags)
{
diff --git a/src/stream_interface.c b/src/stream_interface.c
index a693daa..988bcfc 100644
--- a/src/stream_interface.c
+++ b/src/stream_interface.c
@@ -1366,8 +1366,9 @@
int cur_flags = flags;
/* Compute transient CO_RFL_* flags */
- if (co_data(ic))
- cur_flags |= CO_RFL_BUF_WET;
+ if (co_data(ic)) {
+ cur_flags |= (CO_RFL_BUF_WET | CO_RFL_BUF_NOT_STUCK);
+ }
/* <max> may be null. This is the mux responsibility to set
* CS_FL_RCV_MORE on the CS if more space is needed.