diff --git a/include/haproxy/connection-t.h b/include/haproxy/connection-t.h index 28dbbf4b7..ed41cff82 100644 --- a/include/haproxy/connection-t.h +++ b/include/haproxy/connection-t.h @@ -276,10 +276,11 @@ enum { /* flags that can be passed to xprt->rcv_buf() and mux->rcv_buf() */ enum { - CO_RFL_BUF_WET = 0x0001, /* Buffer still has some output data present */ - CO_RFL_BUF_FLUSH = 0x0002, /* Flush mux's buffers but don't read more data */ - CO_RFL_READ_ONCE = 0x0004, /* don't loop even if the request/response is small */ - CO_RFL_KEEP_RECV = 0x0008, /* Instruct the mux to still wait for read events */ + CO_RFL_BUF_WET = 0x0001, /* Buffer still has some output data present */ + CO_RFL_BUF_FLUSH = 0x0002, /* Flush mux's buffers but don't read more data */ + CO_RFL_READ_ONCE = 0x0004, /* don't loop even if the request/response is small */ + CO_RFL_KEEP_RECV = 0x0008, /* Instruct the mux to still wait for read events */ + CO_RFL_BUF_NOT_STUCK = 0x0010, /* Buffer is not stuck. Optims are possible during data copy */ }; /* flags that can be passed to xprt->snd_buf() and mux->snd_buf() */ diff --git a/src/mux_fcgi.c b/src/mux_fcgi.c index 61142ab5f..84b3aeb5d 100644 --- a/src/mux_fcgi.c +++ b/src/mux_fcgi.c @@ -3910,7 +3910,18 @@ static int fcgi_unsubscribe(struct conn_stream *cs, int event_type, struct wait_ return 0; } -/* Called from the upper layer, to receive data */ +/* Called from the upper layer, to receive data + * + * The caller is responsible for defragmenting if necessary. But + * 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 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 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 20127cc8d..285754548 100644 --- a/src/mux_h1.c +++ b/src/mux_h1.c @@ -3337,7 +3337,18 @@ static int h1_subscribe(struct conn_stream *cs, int event_type, struct wait_even return 0; } -/* Called from the upper layer, to receive data */ +/* Called from the upper layer, to receive data. + * + * The caller is responsible for defragmenting if necessary. But + * 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 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 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 45506c65d..dfe0b3795 100644 --- a/src/mux_h2.c +++ b/src/mux_h2.c @@ -6255,7 +6255,18 @@ static int h2_unsubscribe(struct conn_stream *cs, int event_type, struct wait_ev } -/* Called from the upper layer, to receive data */ +/* Called from the upper layer, to receive data + * + * The caller is responsible for defragmenting if necessary. But + * 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 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 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 86b86e28a..713f11078 100644 --- a/src/mux_pt.c +++ b/src/mux_pt.c @@ -484,6 +484,16 @@ static void mux_pt_shutw(struct conn_stream *cs, enum cs_shw_mode mode) /* * Called from the upper layer, to get more data + * + * The caller is responsible for defragmenting if necessary. But + * 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 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 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 a693daa91..988bcfce3 100644 --- a/src/stream_interface.c +++ b/src/stream_interface.c @@ -1366,8 +1366,9 @@ int si_cs_recv(struct conn_stream *cs) 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); + } /* may be null. This is the mux responsibility to set * CS_FL_RCV_MORE on the CS if more space is needed.