/* Remove from <qcs> stream the acknowledged frames.
* Never fails.
*/
-static void qcs_try_to_consume(struct qcs *qcs)
+static int qcs_try_to_consume(struct qcs *qcs)
{
+ int ret;
struct eb64_node *frm_node;
+ ret = 0;
frm_node = eb64_first(&qcs->tx.acked_frms);
while (frm_node) {
struct quic_stream *strm;
qcs->tx.ack_offset += strm->len;
frm_node = eb64_next(frm_node);
eb64_delete(&strm->offset);
+ ret = 1;
}
+
+ return ret;
}
/* Treat <frm> frame whose packet it is attached to has just been acknowledged. */
static inline void qc_treat_acked_tx_frm(struct quic_frame *frm,
struct ssl_sock_ctx *ctx)
{
+ int stream_acked;
+ struct quic_conn *qc = ctx->conn->qc;
TRACE_PROTO("Removing frame", QUIC_EV_CONN_PRSAFRM, ctx->conn, frm);
+ stream_acked = 0;
switch (frm->type) {
case QUIC_FT_STREAM_8 ... QUIC_FT_STREAM_F:
{
qcs->tx.ack_offset += strm->len;
LIST_DELETE(&frm->list);
pool_free(pool_head_quic_frame, frm);
+ qc->qcc->flags &= ~QC_CF_MUX_MFULL;
+ stream_acked = 1;
}
else {
eb64_insert(&qcs->tx.acked_frms, &strm->offset);
}
- qcs_try_to_consume(qcs);
+ stream_acked |= qcs_try_to_consume(qcs);
}
break;
default:
LIST_DELETE(&frm->list);
pool_free(pool_head_quic_frame, frm);
}
+
+ if (stream_acked) {
+ struct qcc *qcc = qc->qcc;
+
+ if (qcc->subs && qcc->subs->events & SUB_RETRY_SEND) {
+ tasklet_wakeup(qcc->subs->tasklet);
+ qcc->subs->events &= ~SUB_RETRY_SEND;
+ if (!qcc->subs->events)
+ qcc->subs = NULL;
+ }
+ }
}
/* Remove <largest> down to <smallest> node entries from <pkts> tree of TX packet,