struct buffer *qc_stream_buf_get(struct qc_stream_desc *stream);
struct buffer *qc_stream_buf_alloc(struct qc_stream_desc *stream,
- uint64_t offset);
+ uint64_t offset, int *avail);
void qc_stream_buf_release(struct qc_stream_desc *stream);
#endif /* USE_QUIC */
struct qcc *qcc = qcs->qcc;
struct buffer *buf = &qcs->tx.buf;
struct buffer *out = qc_stream_buf_get(qcs->stream);
- int xfer = 0;
+ int xfer = 0, buf_avail;
char fin = 0;
TRACE_ENTER(QMUX_EV_QCS_SEND, qcc->conn, qcs);
if (qcc->flags & QC_CF_CONN_FULL)
goto out;
- out = qc_stream_buf_alloc(qcs->stream, qcs->tx.offset);
+ out = qc_stream_buf_alloc(qcs->stream, qcs->tx.offset,
+ &buf_avail);
if (!out) {
+ if (!buf_avail) {
+ TRACE_ERROR("stream desc alloc failure", QMUX_EV_QCS_SEND, qcc->conn, qcs);
+ goto err;
+ }
+
TRACE_STATE("cannot allocate stream desc buffer", QMUX_EV_QCS_SEND, qcc->conn, qcs);
qcc->flags |= QC_CF_CONN_FULL;
goto out;
return &stream->buf->buf;
}
-/* Check if a new stream buffer can be allocated for the connection <qc>.
- * Returns a boolean.
- */
+/* Returns the count of available buffer left for <qc>. */
static int qc_stream_buf_avail(struct quic_conn *qc)
{
- return qc->stream_buf_count < global.tune.quic_streams_buf;
+ BUG_ON(qc->stream_buf_count > global.tune.quic_streams_buf);
+ return global.tune.quic_streams_buf - qc->stream_buf_count;
}
/* Allocate a new current buffer for <stream>. The buffer limit count for the
* is not NULL prior to this call. The new buffer represents stream payload at
* offset <offset>.
*
- * Returns the buffer or NULL.
+ * Returns the buffer or NULL on error. Caller may check <avail> to ensure if
+ * the connection buffer limit was reached or a fatal error was encountered.
*/
struct buffer *qc_stream_buf_alloc(struct qc_stream_desc *stream,
- uint64_t offset)
+ uint64_t offset, int *avail)
{
struct quic_conn *qc = stream->qc;
/* current buffer must be released first before allocate a new one. */
BUG_ON(stream->buf);
- if (!qc_stream_buf_avail(qc))
+ *avail = qc_stream_buf_avail(qc);
+ if (!*avail)
return NULL;
stream->buf_offset = offset;