comparison src/event/ngx_event_pipe.c @ 4233:aae172db7ac8

Event pipe: reduced number of file buffers used. If possible we now just extend already present file buffer in p->out chain instead of keeping ngx_buf_t for each buffer we've flushed to disk. This saves about 120 bytes of memory per buffer flushed to disk, and resolves high CPU usage observed in edge cases (due to coalescing these buffers on send).
author Maxim Dounin <mdounin@mdounin.ru>
date Mon, 31 Oct 2011 09:54:55 +0000
parents 487ab473f393
children d620f497c50f
comparison
equal deleted inserted replaced
4232:487ab473f393 4233:aae172db7ac8
678 678
679 679
680 static ngx_int_t 680 static ngx_int_t
681 ngx_event_pipe_write_chain_to_temp_file(ngx_event_pipe_t *p) 681 ngx_event_pipe_write_chain_to_temp_file(ngx_event_pipe_t *p)
682 { 682 {
683 ssize_t size, bsize; 683 ssize_t size, bsize, n;
684 ngx_buf_t *b; 684 ngx_buf_t *b;
685 ngx_uint_t prev_last_shadow; 685 ngx_uint_t prev_last_shadow;
686 ngx_chain_t *cl, *tl, *next, *out, **ll, **last_free, fl; 686 ngx_chain_t *cl, *tl, *next, *out, **ll, **last_out, **last_free, fl;
687 687
688 if (p->buf_to_file) { 688 if (p->buf_to_file) {
689 fl.buf = p->buf_to_file; 689 fl.buf = p->buf_to_file;
690 fl.next = p->in; 690 fl.next = p->in;
691 out = &fl; 691 out = &fl;
746 } else { 746 } else {
747 p->in = NULL; 747 p->in = NULL;
748 p->last_in = &p->in; 748 p->last_in = &p->in;
749 } 749 }
750 750
751 if (ngx_write_chain_to_temp_file(p->temp_file, out) == NGX_ERROR) { 751 n = ngx_write_chain_to_temp_file(p->temp_file, out);
752
753 if (n == NGX_ERROR) {
752 return NGX_ABORT; 754 return NGX_ABORT;
753 } 755 }
756
757 if (p->buf_to_file) {
758 p->temp_file->offset = p->buf_to_file->last - p->buf_to_file->pos;
759 n -= p->buf_to_file->last - p->buf_to_file->pos;
760 p->buf_to_file = NULL;
761 out = out->next;
762 }
763
764 if (n > 0) {
765 /* update previous buffer or add new buffer */
766
767 if (p->out) {
768 for (cl = p->out; cl->next; cl = cl->next) { /* void */ }
769
770 b = cl->buf;
771
772 if (b->file_last == p->temp_file->offset) {
773 p->temp_file->offset += n;
774 b->file_last = p->temp_file->offset;
775 goto free;
776 }
777
778 last_out = &cl->next;
779
780 } else {
781 last_out = &p->out;
782 }
783
784 cl = ngx_chain_get_free_buf(p->pool, &p->free);
785 if (cl == NULL) {
786 return NGX_ABORT;
787 }
788
789 b = cl->buf;
790
791 ngx_memzero(b, sizeof(ngx_buf_t));
792
793 b->tag = p->tag;
794
795 b->file = &p->temp_file->file;
796 b->file_pos = p->temp_file->offset;
797 p->temp_file->offset += n;
798 b->file_last = p->temp_file->offset;
799
800 b->in_file = 1;
801 b->temp_file = 1;
802
803 *last_out = cl;
804 }
805
806 free:
754 807
755 for (last_free = &p->free_raw_bufs; 808 for (last_free = &p->free_raw_bufs;
756 *last_free != NULL; 809 *last_free != NULL;
757 last_free = &(*last_free)->next) 810 last_free = &(*last_free)->next)
758 { 811 {
759 /* void */ 812 /* void */
760 } 813 }
761 814
762 if (p->buf_to_file) {
763 p->temp_file->offset = p->buf_to_file->last - p->buf_to_file->pos;
764 p->buf_to_file = NULL;
765 out = out->next;
766 }
767
768 for (cl = out; cl; cl = next) { 815 for (cl = out; cl; cl = next) {
769 next = cl->next; 816 next = cl->next;
770 cl->next = NULL; 817
818 cl->next = p->free;
819 p->free = cl;
771 820
772 b = cl->buf; 821 b = cl->buf;
773 b->file = &p->temp_file->file;
774 b->file_pos = p->temp_file->offset;
775 p->temp_file->offset += b->last - b->pos;
776 b->file_last = p->temp_file->offset;
777
778 b->in_file = 1;
779 b->temp_file = 1;
780
781 if (p->out) {
782 *p->last_out = cl;
783 } else {
784 p->out = cl;
785 }
786 p->last_out = &cl->next;
787 822
788 if (b->last_shadow) { 823 if (b->last_shadow) {
789 824
790 tl = ngx_alloc_chain_link(p->pool); 825 tl = ngx_alloc_chain_link(p->pool);
791 if (tl == NULL) { 826 if (tl == NULL) {