/* These functions are used to compute various channel content sizes */
/*********************************************************************/
-/* 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);
-}
-
/* Returns non-zero if the channel is rewritable, which means that the buffer
* it is attached to has at least <maxrewrite> bytes immediately available.
* This is used to decide when a request or response may be parsed when some
static inline int co_getchr(struct channel *chn)
{
/* closed or empty + imminent close = -2; empty = -1 */
- if (unlikely((chn_cons(chn)->flags & SC_FL_SHUT_DONE) || channel_is_empty(chn))) {
+ if (unlikely((chn_cons(chn)->flags & SC_FL_SHUT_DONE) || !co_data(chn))) {
if (chn_cons(chn)->flags & (SC_FL_SHUT_DONE|SC_FL_SHUT_WANTED))
return -2;
return -1;
if (unlikely(!conn || !conn->ctrl || !conn->ctrl->connect))
return SF_ERR_INTERNAL;
- if (!channel_is_empty(&s->res))
+ if (co_data(&s->res))
conn_flags |= CONNECT_HAS_DATA;
if (s->conn_retries == s->be->conn_retries)
conn_flags |= CONNECT_CAN_USE_TFO;
*/
((cli_conn->flags & CO_FL_EARLY_DATA) ||
((s->be->retry_type & PR_RE_EARLY_ERROR) && !s->conn_retries)) &&
- !channel_is_empty(sc_oc(s->scb)) &&
+ co_data(sc_oc(s->scb)) &&
srv_conn->flags & CO_FL_SSL_WAIT_HS)
srv_conn->flags &= ~(CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN);
#endif
{
return ((s->scf->flags & SC_FL_ERROR) ||
((s->scb->flags & (SC_FL_SHUT_WANTED|SC_FL_SHUT_DONE)) && /* empty and client aborted */
- (channel_is_empty(req) || (s->be->options & PR_O_ABRT_CLOSE))));
+ (!co_data(req) || (s->be->options & PR_O_ABRT_CLOSE))));
}
/* Update back stream connector status for input states SC_ST_ASS, SC_ST_QUE,
/* the client might want to abort */
if ((s->scf->flags & SC_FL_SHUT_DONE) ||
((s->scb->flags & SC_FL_SHUT_WANTED) &&
- (channel_is_empty(req) || (s->be->options & PR_O_ABRT_CLOSE)))) {
+ (!co_data(req) || (s->be->options & PR_O_ABRT_CLOSE)))) {
sc->flags |= SC_FL_NOLINGER;
sc_shutdown(sc);
s->conn_err_type |= STRM_ET_CONN_ABRT;
/* client abort ? */
if ((s->scf->flags & SC_FL_SHUT_DONE) ||
((s->scb->flags & SC_FL_SHUT_WANTED) &&
- (channel_is_empty(req) || (s->be->options & PR_O_ABRT_CLOSE)))) {
+ (!co_data(req) || (s->be->options & PR_O_ABRT_CLOSE)))) {
/* give up */
sc->flags |= SC_FL_NOLINGER;
sc_shutdown(sc);
max = len;
/* closed or empty + imminent close = -1; empty = 0 */
- if (unlikely((chn_cons(chn)->flags & SC_FL_SHUT_DONE) || channel_is_empty(chn))) {
+ if (unlikely((chn_cons(chn)->flags & SC_FL_SHUT_DONE) || !co_data(chn))) {
if (chn_cons(chn)->flags & (SC_FL_SHUT_DONE|SC_FL_SHUT_WANTED))
ret = -1;
goto out;
max = len;
/* closed or empty + imminent close = -1; empty = 0 */
- if (unlikely((chn_cons(chn)->flags & SC_FL_SHUT_DONE) || channel_is_empty(chn))) {
+ if (unlikely((chn_cons(chn)->flags & SC_FL_SHUT_DONE) || !co_data(chn))) {
if (chn_cons(chn)->flags & (SC_FL_SHUT_DONE|SC_FL_SHUT_WANTED))
ret = -1;
goto out;
max = len;
/* closed or empty + imminent close = -1; empty = 0 */
- if (unlikely((chn_cons(chn)->flags & SC_FL_SHUT_DONE) || channel_is_empty(chn))) {
+ if (unlikely((chn_cons(chn)->flags & SC_FL_SHUT_DONE) || !co_data(chn))) {
if (chn_cons(chn)->flags & (SC_FL_SHUT_DONE|SC_FL_SHUT_WANTED))
ret = -1;
goto out;
notification_wake(&ctx->wake_on_write);
/* Wake the tasks which wants to read if the buffer contains data. */
- if (!channel_is_empty(sc_oc(sc)))
+ if (co_data(sc_oc(sc)))
notification_wake(&ctx->wake_on_read);
/* If write notifications are registered, we considers we want
/* nothing else to forward, just waiting for the output buffer
* to be empty and for the shut_wanted to take effect.
*/
- if (channel_is_empty(chn)) {
+ if (!co_data(chn)) {
txn->req.msg_state = HTTP_MSG_CLOSED;
goto http_msg_closed;
}
/* nothing else to forward, just waiting for the output buffer
* to be empty and for the shut_wanted to take effect.
*/
- if (channel_is_empty(chn)) {
+ if (!co_data(chn)) {
txn->rsp.msg_state = HTTP_MSG_CLOSED;
goto http_msg_closed;
}
htx_to_buf(req_htx, &req->buf);
}
}
- else if (!channel_is_empty(res))
+ else if (co_data(res))
applet_wont_consume(appctx);
}
if (!(sc->flags & (SC_FL_EOS|SC_FL_ABRT_DONE)) || !(sc->flags & SC_FL_NOHALF))
return 0;
- if (!channel_is_empty(sc_ic(sc))) {
+ if (co_data(sc_ic(sc))) {
/* the shutdown cannot be forwarded now because
* we should flush outgoing data first. But instruct the output
* channel it should be done ASAP.
return;
if (!sc_ep_test(sc, SE_FL_WAIT_DATA) || /* not waiting for data */
- (channel_is_empty(oc) && !sc_ep_have_ff_data(sc))) /* called with nothing to send ! */
+ (!co_data(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) && !sc_ep_have_ff_data(sc))) /* called with nothing to send ! */
+ if (unlikely(!co_data(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 */
/* OK, so now we know that some data might have been sent, and that we may
* have to poll first. We have to do that too if the buffer is not empty.
*/
- if (channel_is_empty(oc)) {
+ if (!co_data(oc)) {
/* the connection is established but we can't write. Either the
* buffer is empty, or we just refrain from sending because the
* ->o limit was reached. Maybe we just wrote the last
if (likely((sc->flags & SC_FL_SHUT_DONE) ||
((oc->flags & CF_WRITE_EVENT) && sc->state < SC_ST_EST) ||
((oc->flags & CF_WAKE_WRITE) &&
- ((channel_is_empty(oc) && !oc->to_forward) ||
+ ((!co_data(oc) && !oc->to_forward) ||
!sc_state_in(sc->state, SC_SB_EST))))) {
out_wakeup:
if (!(sc->flags & SC_FL_DONT_WAKE))
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) || sc_ep_have_ff_data(sc)) {
+ if (co_data(oc) || sc_ep_have_ff_data(sc)) {
/* (re)start sending */
appctx_wakeup(__sc_appctx(sc));
}
return;
/* Write not closed, update FD status and timeout for writes */
- if (channel_is_empty(oc)) {
+ if (!co_data(oc)) {
/* stop writing */
if (!sc_ep_test(sc, SE_FL_WAIT_DATA)) {
if ((sc->flags & SC_FL_SHUT_WANTED) == 0)
struct task *task = sc_strm_task(sc);
/* process consumer side */
- if (channel_is_empty(oc)) {
+ if (!co_data(oc)) {
struct connection *conn = sc_conn(sc);
if (((sc->flags & (SC_FL_SHUT_DONE|SC_FL_SHUT_WANTED)) == SC_FL_SHUT_WANTED) &&
* parsing.
*/
if (sc_ep_have_ff_data(sc_opposite(sc)) ||
- (!channel_is_empty(ic) && sc_ep_test(sco, SE_FL_WAIT_DATA) &&
+ (co_data(ic) && sc_ep_test(sco, SE_FL_WAIT_DATA) &&
(!(sc->flags & SC_FL_SND_EXP_MORE) || c_full(ic) || ci_data(ic) == 0))) {
int new_len, last_len;
(!(oc->flags & CF_AUTO_CLOSE) &&
!(sc->flags & (SC_FL_SHUT_WANTED|SC_FL_SHUT_DONE)))) &&
(sco->state != SC_ST_EST ||
- (channel_is_empty(oc) && !oc->to_forward)))))) {
+ (!co_data(oc) && !oc->to_forward)))))) {
task_wakeup(task, TASK_WOKEN_IO);
}
else {
}
/* FIXME: Must be reviewed for FF */
- if (channel_is_empty(oc) && !sc_ep_have_ff_data(sc)) {
+ if (!co_data(oc) && !sc_ep_have_ff_data(sc)) {
/* If fast-forwarding is blocked, unblock it now to check for
* receive on the other side
*/
if (sc->flags & SC_FL_SHUT_DONE)
return;
- if (channel_is_empty(oc))
+ if (!co_data(oc))
return;
if (!sc_state_in(sc->state, SC_SB_CON|SC_SB_RDY|SC_SB_EST))
BUG_ON(!conn);
/* If we have data to send, try it now */
- if ((!channel_is_empty(oc) || sc_ep_have_ff_data(sc)) &&
+ if ((co_data(oc) || sc_ep_have_ff_data(sc)) &&
!(sc->wait_event.events & SUB_RETRY_SEND))
sc_conn_send(sc);
if (!sc_conn(sc))
return t;
- 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)))
+ if (!(sc->wait_event.events & SUB_RETRY_SEND) && (co_data(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);
*/
if (scb->state == SC_ST_INI) {
if (!(scb->flags & SC_FL_SHUT_DONE)) {
- if ((req->flags & CF_AUTO_CONNECT) || !channel_is_empty(req)) {
+ if ((req->flags & CF_AUTO_CONNECT) || co_data(req)) {
/* If we have an appctx, there is no connect method, so we
* immediately switch to the connected state, otherwise we
* perform a connection request.
/* shutdown(write) pending */
if (unlikely((scb->flags & (SC_FL_SHUT_DONE|SC_FL_SHUT_WANTED)) == SC_FL_SHUT_WANTED &&
- (channel_is_empty(req) || (req->flags & CF_WRITE_TIMEOUT)))) {
+ (!co_data(req) || (req->flags & CF_WRITE_TIMEOUT)))) {
if (scf->flags & SC_FL_ERROR)
scb->flags |= SC_FL_NOLINGER;
sc_shutdown(scb);
/* shutdown(write) pending */
if (unlikely((scf->flags & (SC_FL_SHUT_DONE|SC_FL_SHUT_WANTED)) == SC_FL_SHUT_WANTED &&
- (channel_is_empty(res) || (res->flags & CF_WRITE_TIMEOUT)))) {
+ (!co_data(res) || (res->flags & CF_WRITE_TIMEOUT)))) {
sc_shutdown(scf);
}