Mercurial > hg > nginx-vendor-current
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 |