/* These functions are used to compute various channel content sizes */
/*********************************************************************/
-/* Reports non-zero if the channel is empty, which means both its
- * buffer and pipe on the opposite SE are empty. The construct looks
- * strange but is jump-less and much more efficient on both 32 and
- * 64-bit than the boolean test.
+/* Reports non-zero if the channel is empty, which means its buffer is
+ * empty. The construct looks strange but is jump-less and much more efficient
+ * on both 32 and 64-bit than the boolean test.
*/
static inline unsigned int channel_is_empty(const struct channel *c)
{
- return (!co_data(c) && !sc_ep_have_ff_data(chn_cons(c)));
+ return !co_data(c);
}
/* Returns non-zero if the channel is rewritable, which means that the buffer
return;
if (!sc_ep_test(sc, SE_FL_WAIT_DATA) || /* not waiting for data */
- channel_is_empty(oc)) /* called with nothing to send ! */
+ (channel_is_empty(oc) && !sc_ep_have_ff_data(sc))) /* called with nothing to send ! */
return;
/* Otherwise there are remaining data to be sent in the buffer,
(sc->flags & SC_FL_SHUT_DONE)))
return;
- if (unlikely(channel_is_empty(oc))) /* called with nothing to send ! */
+ if (unlikely(channel_is_empty(oc) && !sc_ep_have_ff_data(sc))) /* called with nothing to send ! */
return;
if (!sc_ep_have_ff_data(sc) && /* data wants to be fast-forwarded ASAP */
if (!sc_ep_test(sc, SE_FL_WAIT_DATA|SE_FL_WONT_CONSUME) && !(sc->flags & SC_FL_SHUT_WANTED))
return;
- if (!channel_is_empty(oc)) {
+ if (!channel_is_empty(oc) || sc_ep_have_ff_data(sc)) {
/* (re)start sending */
appctx_wakeup(__sc_appctx(sc));
}
}
/* FIXME: Must be reviewed for FF */
- if (channel_is_empty(oc)) {
+ if (channel_is_empty(oc) && !sc_ep_have_ff_data(sc)) {
/* If fast-forwarding is blocked, unblock it now to check for
* receive on the other side
*/
BUG_ON(!conn);
/* If we have data to send, try it now */
- if (!channel_is_empty(oc) && !(sc->wait_event.events & SUB_RETRY_SEND))
+ if ((!channel_is_empty(oc) || sc_ep_have_ff_data(sc)) &&
+ !(sc->wait_event.events & SUB_RETRY_SEND))
sc_conn_send(sc);
/* First step, report to the stream connector what was detected at the
if (!sc_conn(sc))
return t;
- if (!(sc->wait_event.events & SUB_RETRY_SEND) && (!channel_is_empty(sc_oc(sc)) || (sc->sedesc->iobuf.flags & IOBUF_FL_FF_BLOCKED)))
+ if (!(sc->wait_event.events & SUB_RETRY_SEND) && (!channel_is_empty(sc_oc(sc)) || sc_ep_have_ff_data(sc) || (sc->sedesc->iobuf.flags & IOBUF_FL_FF_BLOCKED)))
ret = sc_conn_send(sc);
if (!(sc->wait_event.events & SUB_RETRY_RECV))
ret |= sc_conn_recv(sc);