goto err;
}
- if (!qc_send_mux(qcc->conn->handle.qc, frms))
+ if (!qc_send_mux(qcc->conn->handle.qc, frms)) {
+ /* TODO should subscribe only for a transient send error */
+ TRACE_DEVEL("error on send, subscribing", QMUX_EV_QCC_SEND, qcc->conn);
+ qcc->conn->xprt->subscribe(qcc->conn, qcc->conn->xprt_ctx,
+ SUB_RETRY_SEND, &qcc->wait_event);
goto err;
+ }
/* If there is frames left at this stage, transport layer is blocked.
* Subscribe on it to retry later.
int qc_notify_send(struct quic_conn *qc)
{
if (qc->subs && qc->subs->events & SUB_RETRY_SEND) {
- if (quic_path_prep_data(qc->path)) {
+ if (quic_path_prep_data(qc->path) &&
+ (!qc_test_fd(qc) || !fd_send_active(qc->fd))) {
tasklet_wakeup(qc->subs->tasklet);
qc->subs->events &= ~SUB_RETRY_SEND;
if (!qc->subs->events)
TRACE_DEVEL("send ready", QUIC_EV_CONN_RCV, qc);
fd_stop_send(fd);
tasklet_wakeup_after(NULL, qc->wait_event.tasklet);
+ qc_notify_send(qc);
}
if (fd_recv_ready(fd)) {