MINOR: quic: decode as much STREAM as possible
Add a loop in the bidi STREAM function. This will call repeatdly
qcc_decode_qcs() and dequeue buffered frames.
This is useful when reception of more data is interrupted because the
MUX buffer was full. qcc_decode_qcs() has probably free some space so it
is useful to immediatly retry reception of buffered frames of the qcs
tree.
This may fix occurences of stalled Rx transfers with large payload.
Note however that there is still room for improvment. The conn-stream
layer is not able at this moment to retrigger demuxing. This is because
the mux io-handler does not treat Rx : this may continue to cause
stalled tranfers.
diff --git a/src/h3.c b/src/h3.c
index f5da761..fe3ae13 100644
--- a/src/h3.c
+++ b/src/h3.c
@@ -321,6 +321,10 @@
h3s->demux_frame_len -= ret;
}
+ /* TODO may be useful to wakeup the MUX if blocked due to full buffer.
+ * However, currently, io-cb of MUX does not handle Rx.
+ */
+
return 0;
}
diff --git a/src/xprt_quic.c b/src/xprt_quic.c
index 773b62b..5820886 100644
--- a/src/xprt_quic.c
+++ b/src/xprt_quic.c
@@ -2139,7 +2139,7 @@
struct quic_rx_strm_frm *frm;
struct eb64_node *frm_node;
struct qcs *qcs = NULL;
- size_t done;
+ size_t done, buf_was_full;
int ret;
ret = qcc_recv(qc->qcc, strm_frm->id, strm_frm->len,
@@ -2176,6 +2176,13 @@
return 1;
}
+ /* Decode the data if buffer is already full as it's not possible to
+ * dequeue a frame in this condition.
+ */
+ if (b_full(&qcs->rx.buf))
+ qcc_decode_qcs(qc->qcc, qcs);
+
+ retry:
/* Frame received (partially or not) by the mux.
* If there is buffered frame for next offset, it may be possible to
* receive them now.
@@ -2212,9 +2219,17 @@
pool_free(pool_head_quic_rx_strm_frm, frm);
}
+ buf_was_full = b_full(&qcs->rx.buf);
/* Decode the received data. */
qcc_decode_qcs(qc->qcc, qcs);
+ /* Buffer was full so the reception was stopped. Now the buffer has
+ * space available thanks to qcc_decode_qcs(). We can now retry to
+ * handle more data.
+ */
+ if (buf_was_full && !b_full(&qcs->rx.buf))
+ goto retry;
+
return 1;
}