comparison src/event/ngx_event_pipe.c @ 646:615b5ea36fc0 NGINX_1_1_7

nginx 1.1.7 *) Feature: support of several resolvers in the "resolver" directive. Thanks to Kirill A. Korinskiy. *) Bugfix: a segmentation fault occurred on start or while reconfiguration if the "ssl" directive was used at http level and there was no "ssl_certificate" defined. *) Bugfix: reduced memory consumption while proxying of big files if they were buffered to disk. *) Bugfix: a segmentation fault might occur in a worker process if "proxy_http_version 1.1" directive was used. *) Bugfix: in the "expires @time" directive.
author Igor Sysoev <http://sysoev.ru>
date Mon, 31 Oct 2011 00:00:00 +0400
parents eb208e0cf44d
children d0f7a625f27c
comparison
equal deleted inserted replaced
645:e461dead01e9 646:615b5ea36fc0
13 static ngx_int_t ngx_event_pipe_read_upstream(ngx_event_pipe_t *p); 13 static ngx_int_t ngx_event_pipe_read_upstream(ngx_event_pipe_t *p);
14 static ngx_int_t ngx_event_pipe_write_to_downstream(ngx_event_pipe_t *p); 14 static ngx_int_t ngx_event_pipe_write_to_downstream(ngx_event_pipe_t *p);
15 15
16 static ngx_int_t ngx_event_pipe_write_chain_to_temp_file(ngx_event_pipe_t *p); 16 static ngx_int_t ngx_event_pipe_write_chain_to_temp_file(ngx_event_pipe_t *p);
17 static ngx_inline void ngx_event_pipe_remove_shadow_links(ngx_buf_t *buf); 17 static ngx_inline void ngx_event_pipe_remove_shadow_links(ngx_buf_t *buf);
18 static ngx_inline void ngx_event_pipe_free_shadow_raw_buf(ngx_chain_t **free,
19 ngx_buf_t *buf);
20 static ngx_int_t ngx_event_pipe_drain_chains(ngx_event_pipe_t *p); 18 static ngx_int_t ngx_event_pipe_drain_chains(ngx_event_pipe_t *p);
21 19
22 20
23 ngx_int_t 21 ngx_int_t
24 ngx_event_pipe(ngx_event_pipe_t *p, ngx_int_t do_write) 22 ngx_event_pipe(ngx_event_pipe_t *p, ngx_int_t do_write)
574 572
575 for ( ;; ) { 573 for ( ;; ) {
576 if (p->out) { 574 if (p->out) {
577 cl = p->out; 575 cl = p->out;
578 576
579 if (cl->buf->recycled 577 if (cl->buf->recycled) {
580 && bsize + cl->buf->last - cl->buf->pos > p->busy_size) 578 ngx_log_error(NGX_LOG_ALERT, p->log, 0,
581 { 579 "recycled buffer in pipe out chain");
582 flush = 1;
583 break;
584 } 580 }
585 581
586 p->out = p->out->next; 582 p->out = p->out->next;
587
588 ngx_event_pipe_free_shadow_raw_buf(&p->free_raw_bufs, cl->buf);
589 583
590 } else if (!p->cacheable && p->in) { 584 } else if (!p->cacheable && p->in) {
591 cl = p->in; 585 cl = p->in;
592 586
593 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, p->log, 0, 587 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, p->log, 0,
594 "pipe write buf ls:%d %p %z", 588 "pipe write buf ls:%d %p %z",
595 cl->buf->last_shadow, 589 cl->buf->last_shadow,
596 cl->buf->pos, 590 cl->buf->pos,
597 cl->buf->last - cl->buf->pos); 591 cl->buf->last - cl->buf->pos);
598 592
599 if (cl->buf->recycled 593 if (cl->buf->recycled && prev_last_shadow) {
600 && cl->buf->last_shadow 594 if (bsize + cl->buf->end - cl->buf->start > p->busy_size) {
601 && bsize + cl->buf->last - cl->buf->pos > p->busy_size) 595 flush = 1;
602 { 596 break;
603 if (!prev_last_shadow) {
604 p->in = p->in->next;
605
606 cl->next = NULL;
607
608 if (out) {
609 *ll = cl;
610 } else {
611 out = cl;
612 }
613 } 597 }
614 598
615 flush = 1; 599 bsize += cl->buf->end - cl->buf->start;
616 break;
617 } 600 }
618 601
619 prev_last_shadow = cl->buf->last_shadow; 602 prev_last_shadow = cl->buf->last_shadow;
620 603
621 p->in = p->in->next; 604 p->in = p->in->next;
622 605
623 } else { 606 } else {
624 break; 607 break;
625 }
626
627 if (cl->buf->recycled) {
628 bsize += cl->buf->last - cl->buf->pos;
629 } 608 }
630 609
631 cl->next = NULL; 610 cl->next = NULL;
632 611
633 if (out) { 612 if (out) {
699 678
700 679
701 static ngx_int_t 680 static ngx_int_t
702 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)
703 { 682 {
704 ssize_t size, bsize; 683 ssize_t size, bsize, n;
705 ngx_buf_t *b; 684 ngx_buf_t *b;
706 ngx_chain_t *cl, *tl, *next, *out, **ll, **last_free, fl; 685 ngx_uint_t prev_last_shadow;
686 ngx_chain_t *cl, *tl, *next, *out, **ll, **last_out, **last_free, fl;
707 687
708 if (p->buf_to_file) { 688 if (p->buf_to_file) {
709 fl.buf = p->buf_to_file; 689 fl.buf = p->buf_to_file;
710 fl.next = p->in; 690 fl.next = p->in;
711 out = &fl; 691 out = &fl;
717 if (!p->cacheable) { 697 if (!p->cacheable) {
718 698
719 size = 0; 699 size = 0;
720 cl = out; 700 cl = out;
721 ll = NULL; 701 ll = NULL;
702 prev_last_shadow = 1;
722 703
723 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, p->log, 0, 704 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, p->log, 0,
724 "pipe offset: %O", p->temp_file->offset); 705 "pipe offset: %O", p->temp_file->offset);
725 706
726 do { 707 do {
727 bsize = cl->buf->last - cl->buf->pos; 708 bsize = cl->buf->last - cl->buf->pos;
728 709
729 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, p->log, 0, 710 ngx_log_debug4(NGX_LOG_DEBUG_EVENT, p->log, 0,
730 "pipe buf %p, pos %p, size: %z", 711 "pipe buf ls:%d %p, pos %p, size: %z",
731 cl->buf->start, cl->buf->pos, bsize); 712 cl->buf->last_shadow, cl->buf->start,
732 713 cl->buf->pos, bsize);
733 if ((size + bsize > p->temp_file_write_size) 714
734 || (p->temp_file->offset + size + bsize > p->max_temp_file_size)) 715 if (prev_last_shadow
716 && ((size + bsize > p->temp_file_write_size)
717 || (p->temp_file->offset + size + bsize
718 > p->max_temp_file_size)))
735 { 719 {
736 break; 720 break;
737 } 721 }
722
723 prev_last_shadow = cl->buf->last_shadow;
738 724
739 size += bsize; 725 size += bsize;
740 ll = &cl->next; 726 ll = &cl->next;
741 cl = cl->next; 727 cl = cl->next;
742 728
760 } else { 746 } else {
761 p->in = NULL; 747 p->in = NULL;
762 p->last_in = &p->in; 748 p->last_in = &p->in;
763 } 749 }
764 750
765 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) {
766 return NGX_ABORT; 754 return NGX_ABORT;
767 } 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:
768 807
769 for (last_free = &p->free_raw_bufs; 808 for (last_free = &p->free_raw_bufs;
770 *last_free != NULL; 809 *last_free != NULL;
771 last_free = &(*last_free)->next) 810 last_free = &(*last_free)->next)
772 { 811 {
773 /* void */ 812 /* void */
774 } 813 }
775 814
776 if (p->buf_to_file) {
777 p->temp_file->offset = p->buf_to_file->last - p->buf_to_file->pos;
778 p->buf_to_file = NULL;
779 out = out->next;
780 }
781
782 for (cl = out; cl; cl = next) { 815 for (cl = out; cl; cl = next) {
783 next = cl->next; 816 next = cl->next;
784 cl->next = NULL; 817
818 cl->next = p->free;
819 p->free = cl;
785 820
786 b = cl->buf; 821 b = cl->buf;
787 b->file = &p->temp_file->file;
788 b->file_pos = p->temp_file->offset;
789 p->temp_file->offset += b->last - b->pos;
790 b->file_last = p->temp_file->offset;
791
792 b->in_file = 1;
793 b->temp_file = 1;
794
795 if (p->out) {
796 *p->last_out = cl;
797 } else {
798 p->out = cl;
799 }
800 p->last_out = &cl->next;
801 822
802 if (b->last_shadow) { 823 if (b->last_shadow) {
803 824
804 tl = ngx_alloc_chain_link(p->pool); 825 tl = ngx_alloc_chain_link(p->pool);
805 if (tl == NULL) { 826 if (tl == NULL) {
911 932
912 buf->shadow = NULL; 933 buf->shadow = NULL;
913 } 934 }
914 935
915 936
916 static ngx_inline void
917 ngx_event_pipe_free_shadow_raw_buf(ngx_chain_t **free, ngx_buf_t *buf)
918 {
919 ngx_buf_t *s;
920 ngx_chain_t *cl, **ll;
921
922 if (buf->shadow == NULL) {
923 return;
924 }
925
926 for (s = buf->shadow; !s->last_shadow; s = s->shadow) { /* void */ }
927
928 ll = free;
929
930 for (cl = *free; cl; cl = cl->next) {
931 if (cl->buf == s) {
932 *ll = cl->next;
933 break;
934 }
935
936 if (cl->buf->shadow) {
937 break;
938 }
939
940 ll = &cl->next;
941 }
942 }
943
944
945 ngx_int_t 937 ngx_int_t
946 ngx_event_pipe_add_free_buf(ngx_event_pipe_t *p, ngx_buf_t *b) 938 ngx_event_pipe_add_free_buf(ngx_event_pipe_t *p, ngx_buf_t *b)
947 { 939 {
948 ngx_chain_t *cl; 940 ngx_chain_t *cl;
949 941