if (!conn->err_code ||
conn->err_code == CO_ER_PRX_EMPTY || conn->err_code == CO_ER_PRX_ABORT ||
conn->err_code == CO_ER_CIP_EMPTY || conn->err_code == CO_ER_CIP_ABORT ||
- conn->err_code == CO_ER_SSL_EMPTY || conn->err_code == CO_ER_SSL_ABORT)
+ conn->err_code == CO_ER_SSL_EMPTY || conn->err_code == CO_ER_SSL_ABORT ||
+ conn->err_code == CO_ER_QSTRM)
log = 0;
}
conn->err_code = CO_ER_CIP_TIMEOUT;
else if (conn->flags & CO_FL_SSL_WAIT_HS)
conn->err_code = CO_ER_SSL_TIMEOUT;
+ else if (conn->flags & CO_FL_QSTRM_RECV)
+ conn->err_code = CO_ER_QSTRM;
}
sess_log_embryonic(sess);
do {
ret = ctx->ops_lower->rcv_buf(conn, ctx->ctx_lower, buf, b_room(buf), NULL, 0, 0);
- BUG_ON(conn->flags & CO_FL_ERROR);
+ if (conn->flags & CO_FL_ERROR)
+ goto fail;
} while (ret);
if (!b_data(buf))
return 0;
fail:
+ conn->err_code = CO_ER_QSTRM;
conn->flags |= CO_FL_ERROR;
return 0;
}
sent = ctx->ops_lower->snd_buf(conn, ctx->ctx_lower, buf, b_data(buf),
NULL, 0, 0);
+ if (conn->flags & CO_FL_ERROR)
+ goto fail;
+
b_del(buf, sent);
if (b_data(buf))
goto retry;
return 0;
fail:
+ conn->err_code = CO_ER_QSTRM;
conn->flags |= CO_FL_ERROR;
return 0;
}
{
struct xprt_qstrm_ctx *ctx = context;
struct connection *conn = ctx->conn;
- int ret;
if (conn->flags & CO_FL_QSTRM_SEND) {
if (!conn_send_qstrm(conn, ctx, CO_FL_QSTRM_SEND)) {
- ctx->ops_lower->subscribe(conn, ctx->ctx_lower,
- SUB_RETRY_SEND, &ctx->wait_event);
+ if (!(conn->flags & CO_FL_ERROR)) {
+ ctx->ops_lower->subscribe(conn, ctx->ctx_lower,
+ SUB_RETRY_SEND, &ctx->wait_event);
+ }
goto out;
}
}
if (conn->flags & CO_FL_QSTRM_RECV) {
if (!conn_recv_qstrm(conn, ctx, CO_FL_QSTRM_RECV)) {
- ctx->ops_lower->subscribe(conn, ctx->ctx_lower,
- SUB_RETRY_RECV, &ctx->wait_event);
+ if (!(conn->flags & CO_FL_ERROR)) {
+ ctx->ops_lower->subscribe(conn, ctx->ctx_lower,
+ SUB_RETRY_RECV, &ctx->wait_event);
+ }
goto out;
}
}
out:
if ((conn->flags & CO_FL_ERROR) ||
!(conn->flags & (CO_FL_QSTRM_RECV|CO_FL_QSTRM_SEND))) {
+ /* XPRT should be unsubscribed when transfer done or on error. */
+ BUG_ON(ctx->wait_event.events);
+
/* MUX will access members from xprt_ctx on init, so create
* operation should be called before any members are resetted.
*/
- ret = conn_create_mux(conn, NULL);
- BUG_ON(ret);
+ if (conn_create_mux(conn, NULL) == 0)
+ conn->mux->wake(conn);
conn->xprt_ctx = ctx->ctx_lower;
conn->xprt = ctx->ops_lower;
- conn->mux->wake(conn);
b_free(&ctx->rxbuf);
b_free(&ctx->txbuf);