TRACE_ENTER(QMUX_EV_QCC_RECV, qcc->conn);
+ if (qcc->flags & QC_CF_ERR_CONN)
+ return 0;
+
if (!b_size(buf)) {
if (!b_alloc(buf, DB_MUX_RX)) {
TRACE_ERROR("rx qstrm buf alloc failure", QMUX_EV_QCC_RECV);
/* Previous realign operation should ensure send cannot result in data wrapping. */
BUG_ON(b_data(buf) && b_tail(buf) == b_orig(buf));
ret = conn->xprt->rcv_buf(conn, conn->xprt_ctx, buf, b_contig_space(buf), NULL, 0, 0);
- BUG_ON(conn->flags & CO_FL_ERROR); /* TODO handle errors */
+ if (qcc->conn->flags & CO_FL_ERROR)
+ goto out;
/* Previous realign operation should ensure send cannot result in data wrapping. */
BUG_ON(b_data(buf) != b_contig_data(buf, 0));
}
}
} while (ret > 0);
- if (!conn_xprt_read0_pending(qcc->conn)) {
+ out:
+ if ((conn->flags & CO_FL_ERROR) || conn_xprt_read0_pending(conn)) {
+ qcc->flags |= QC_CF_ERR_CONN;
+ }
+ else {
conn->xprt->subscribe(conn, conn->xprt_ctx, SUB_RETRY_RECV,
&qcc->wait_event);
}
/* Purge buffer first if remaining data to send. */
if (b_data(buf)) {
sent = conn->xprt->snd_buf(conn, conn->xprt_ctx, buf, b_data(buf), NULL, 0, 0);
+ if (conn->flags & CO_FL_ERROR)
+ goto out;
if (!sent) {
TRACE_DEVEL("snd_buf interrupted", QMUX_EV_QCC_SEND, qcc->conn);
goto out;
b_add(buf, pos - old);
sent = conn->xprt->snd_buf(conn, conn->xprt_ctx, buf, b_data(buf), NULL, 0, 0);
+ if (conn->flags & CO_FL_ERROR)
+ goto out;
if (!sent) {
TRACE_DEVEL("snd_buf interrupted", QMUX_EV_QCC_SEND, qcc->conn);
if (split_frm)
}
out:
- if (conn->flags & CO_FL_ERROR) {
- /* TODO */
+ if ((conn->flags & CO_FL_ERROR)) {
+ qcc->flags |= QC_CF_ERR_CONN;
+ ret = -1;
}
else if (!LIST_ISEMPTY(frms)) {
if (!(qcc->wait_event.events & SUB_RETRY_SEND))