Mercurial > hg > nginx
comparison src/event/quic/ngx_event_quic_frames.c @ 8946:56dec0d4e5b1 quic
QUIC: avoid excessive buffer allocations in stream output.
Previously, when a few bytes were send to a QUIC stream by the application, a
4K buffer was allocated for these bytes. Then a STREAM frame was created and
that entire buffer was used as data for that frame. The frame with the buffer
were in use up until the frame was acked by client. Meanwhile, when more
bytes were send to the stream, more buffers were allocated and assigned as
data to newer STREAM frames. In this scenario most buffer memory is unused.
Now the unused part of the stream output buffer is available for further
stream output while earlier parts of the buffer are waiting to be acked.
This is achieved by splitting the output buffer.
author | Roman Arutyunyan <arut@nginx.com> |
---|---|
date | Fri, 24 Dec 2021 18:13:51 +0300 |
parents | a6a328ebd362 |
children | 6ccf3867959a |
comparison
equal
deleted
inserted
replaced
8945:e72db9162180 | 8946:56dec0d4e5b1 |
---|---|
480 } | 480 } |
481 | 481 |
482 | 482 |
483 ngx_int_t | 483 ngx_int_t |
484 ngx_quic_order_bufs(ngx_connection_t *c, ngx_chain_t **out, ngx_chain_t *in, | 484 ngx_quic_order_bufs(ngx_connection_t *c, ngx_chain_t **out, ngx_chain_t *in, |
485 size_t offset) | 485 off_t limit, off_t offset) |
486 { | 486 { |
487 off_t n; | |
487 u_char *p; | 488 u_char *p; |
488 size_t n; | |
489 ngx_buf_t *b; | 489 ngx_buf_t *b; |
490 ngx_chain_t *cl, *sl; | 490 ngx_chain_t *cl, *sl; |
491 | 491 |
492 while (in) { | 492 while (in && limit) { |
493 cl = *out; | 493 cl = *out; |
494 | 494 |
495 if (cl == NULL) { | 495 if (cl == NULL) { |
496 cl = ngx_quic_alloc_buf(c); | 496 cl = ngx_quic_alloc_buf(c); |
497 if (cl == NULL) { | 497 if (cl == NULL) { |
521 | 521 |
522 cl->next = sl; | 522 cl->next = sl; |
523 continue; | 523 continue; |
524 } | 524 } |
525 | 525 |
526 for (p = b->pos + offset; p != b->last && in; /* void */ ) { | 526 for (p = b->pos + offset; p != b->last && in && limit; /* void */ ) { |
527 n = ngx_min(b->last - p, in->buf->last - in->buf->pos); | 527 n = ngx_min(b->last - p, in->buf->last - in->buf->pos); |
528 n = ngx_min(n, limit); | |
528 | 529 |
529 if (b->sync) { | 530 if (b->sync) { |
530 ngx_memcpy(p, in->buf->pos, n); | 531 ngx_memcpy(p, in->buf->pos, n); |
531 } | 532 } |
532 | 533 |
533 p += n; | 534 p += n; |
534 in->buf->pos += n; | 535 in->buf->pos += n; |
535 offset += n; | 536 offset += n; |
537 limit -= n; | |
536 | 538 |
537 if (in->buf->pos == in->buf->last) { | 539 if (in->buf->pos == in->buf->last) { |
538 in = in->next; | 540 in = in->next; |
539 } | 541 } |
540 } | 542 } |