diff --git a/src/quic_stream.c b/src/quic_stream.c index da86e04ff9..727636b06a 100644 --- a/src/quic_stream.c +++ b/src/quic_stream.c @@ -17,6 +17,34 @@ DECLARE_STATIC_POOL(pool_head_quic_stream_buf, "qc_stream_buf", sizeof(struct qc_stream_buf)); +static void qc_stream_buf_free(struct qc_stream_desc *stream, + struct qc_stream_buf **stream_buf) +{ + struct quic_conn *qc = stream->qc; + struct buffer *buf = &(*stream_buf)->buf; + + LIST_DEL_INIT(&(*stream_buf)->list); + if (*stream_buf == stream->buf) { + /* current buf must always be last entry in buflist */ + BUG_ON(!LIST_ISEMPTY(&stream->buf_list)); + stream->buf = NULL; + } + + b_free(buf); + offer_buffers(NULL, 1); + pool_free(pool_head_quic_stream_buf, *stream_buf); + *stream_buf = NULL; + + /* notify MUX about available buffers. */ + --qc->stream_buf_count; + if (qc->mux_state == QC_MUX_READY) { + if (qc->qcc->flags & QC_CF_CONN_FULL) { + qc->qcc->flags &= ~QC_CF_CONN_FULL; + tasklet_wakeup(qc->qcc->wait_event.tasklet); + } + } +} + /* Allocate a new stream descriptor with id . The caller is responsible to * store the stream in the appropriate tree. -1 special value must be used for * a CRYPTO data stream, the type being ignored. @@ -92,7 +120,6 @@ int qc_stream_desc_ack(struct qc_stream_desc **stream, size_t offset, size_t len { struct qc_stream_desc *s = *stream; struct qc_stream_buf *stream_buf; - struct quic_conn *qc = s->qc; struct buffer *buf; size_t diff; @@ -110,39 +137,17 @@ int qc_stream_desc_ack(struct qc_stream_desc **stream, size_t offset, size_t len s->ack_offset += diff; b_del(buf, diff); - /* nothing more to do if buf still not empty. */ - if (b_data(buf)) - return diff; + /* Free oldest buffer if all data acknowledged. */ + if (!b_data(buf)) { + qc_stream_buf_free(s, &stream_buf); - /* buf is empty and can now be freed. Do not forget to reset current - * buf ptr if we were working on it. - */ - LIST_DELETE(&stream_buf->list); - if (stream_buf == s->buf) { - /* current buf must always be last entry in buflist */ - BUG_ON(!LIST_ISEMPTY(&s->buf_list)); - s->buf = NULL; - } - - b_free(buf); - pool_free(pool_head_quic_stream_buf, stream_buf); - offer_buffers(NULL, 1); - - /* notify MUX about available buffers. */ - --qc->stream_buf_count; - if (qc->mux_state == QC_MUX_READY) { - if (qc->qcc->flags & QC_CF_CONN_FULL) { - qc->qcc->flags &= ~QC_CF_CONN_FULL; - tasklet_wakeup(qc->qcc->wait_event.tasklet); + /* Free stream instance if already released and no buffers left. */ + if (s->release && LIST_ISEMPTY(&s->buf_list)) { + qc_stream_desc_free(s, 0); + *stream = NULL; } } - /* Free stream instance if already released and no buffers left. */ - if (s->release && LIST_ISEMPTY(&s->buf_list)) { - qc_stream_desc_free(s, 0); - *stream = NULL; - } - return diff; }