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 }