MINOR: channel: Rely on HTX version if appropriate in channel_may_recv()
When channel_may_recv() is called for an HTX stream, the HTX version,
channel_htx_may_recv() is called. This patch is mandatory to fix a bug
related to the abortonclose option.
(cherry picked from commit 1c235e57d0087e86074178f682c24f8aa44e0fcd)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit d54760ed1a531c8988e6d4f12800151295c8eaf9)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit e1616ae874cfd95ea78d082640b3458185f0774f)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
diff --git a/include/proto/channel.h b/include/proto/channel.h
index 4872aa3..7dd6beb 100644
--- a/include/proto/channel.h
+++ b/include/proto/channel.h
@@ -436,27 +436,18 @@
return chn_cons(chn)->state == SI_ST_EST;
}
-/* Returns non-zero if the channel can still receive data. This is used to
- * decide when to stop reading into a buffer when we want to ensure that we
- * leave the reserve untouched after all pending outgoing data are forwarded.
- * The reserved space is taken into account if ->to_forward indicates that an
- * end of transfer is close to happen. Note that both ->buf.o and ->to_forward
- * are considered as available since they're supposed to leave the buffer. The
- * test is optimized to avoid as many operations as possible for the fast case
- * and to be used as an "if" condition. Just like channel_recv_limit(), we
- * never allow to overwrite the reserve until the output stream interface is
- * connected, otherwise we could spin on a POST with http-send-name-header.
- */
-static inline int channel_may_recv(const struct channel *chn)
+/* HTX version of channel_may_recv(). Returns non-zero if the channel can still
+ * receive data. */
+static inline int channel_htx_may_recv(const struct channel *chn, const struct htx *htx)
{
- int rem = chn->buf.size;
+ uint32_t rem;
- if (b_is_null(&chn->buf))
+ if (!htx->size)
return 1;
- rem -= b_data(&chn->buf);
+ rem = htx_free_data_space(htx);
if (!rem)
- return 0; /* buffer already full */
+ return 0; /* htx already full */
if (rem > global.tune.maxrewrite)
return 1; /* reserve not yet reached */
@@ -471,29 +462,44 @@
* the reserve, and we want to ensure they're covered by scheduled
* forwards.
*/
- rem = ci_data(chn) + global.tune.maxrewrite - chn->buf.size;
- return rem < 0 || (unsigned int)rem < chn->to_forward;
+ rem += co_data(chn);
+ if (rem > global.tune.maxrewrite)
+ return 1;
+
+ return (global.tune.maxrewrite - rem < chn->to_forward);
}
-/* HTX version of channel_may_recv(). Returns non-zero if the channel can still
- * receive data. */
-static inline int channel_htx_may_recv(const struct channel *chn, const struct htx *htx)
+/* Returns non-zero if the channel can still receive data. This is used to
+ * decide when to stop reading into a buffer when we want to ensure that we
+ * leave the reserve untouched after all pending outgoing data are forwarded.
+ * The reserved space is taken into account if ->to_forward indicates that an
+ * end of transfer is close to happen. Note that both ->buf.o and ->to_forward
+ * are considered as available since they're supposed to leave the buffer. The
+ * test is optimized to avoid as many operations as possible for the fast case
+ * and to be used as an "if" condition. Just like channel_recv_limit(), we
+ * never allow to overwrite the reserve until the output stream interface is
+ * connected, otherwise we could spin on a POST with http-send-name-header.
+ */
+static inline int channel_may_recv(const struct channel *chn)
{
- uint32_t rem;
+ int rem = chn->buf.size;
- if (!htx->size)
- return 1;
+ if (IS_HTX_STRM(chn_strm(chn)))
+ return channel_htx_may_recv(chn, htxbuf(&chn->buf));
- if (!channel_may_send(chn))
- return 0; /* don't touch reserve until we can send */
+ if (b_is_null(&chn->buf))
+ return 1;
- rem = htx_free_data_space(htx);
+ rem -= b_data(&chn->buf);
if (!rem)
- return 0; /* htx already full */
+ return 0; /* buffer already full */
if (rem > global.tune.maxrewrite)
return 1; /* reserve not yet reached */
+ if (!channel_may_send(chn))
+ return 0; /* don't touch reserve until we can send */
+
/* Now we know there's some room left in the reserve and we may
* forward. As long as i-to_fwd < size-maxrw, we may still
* receive. This is equivalent to i+maxrw-size < to_fwd,
@@ -501,11 +507,8 @@
* the reserve, and we want to ensure they're covered by scheduled
* forwards.
*/
- rem += co_data(chn);
- if (rem > global.tune.maxrewrite)
- return 1;
-
- return (global.tune.maxrewrite - rem < chn->to_forward);
+ rem = ci_data(chn) + global.tune.maxrewrite - chn->buf.size;
+ return rem < 0 || (unsigned int)rem < chn->to_forward;
}
/* Returns true if the channel's input is already closed */