diff 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
line wrap: on
line diff
--- a/src/event/ngx_event_pipe.c
+++ b/src/event/ngx_event_pipe.c
@@ -15,8 +15,6 @@ static ngx_int_t ngx_event_pipe_write_to
 
 static ngx_int_t ngx_event_pipe_write_chain_to_temp_file(ngx_event_pipe_t *p);
 static ngx_inline void ngx_event_pipe_remove_shadow_links(ngx_buf_t *buf);
-static ngx_inline void ngx_event_pipe_free_shadow_raw_buf(ngx_chain_t **free,
-                                                          ngx_buf_t *buf);
 static ngx_int_t ngx_event_pipe_drain_chains(ngx_event_pipe_t *p);
 
 
@@ -576,17 +574,13 @@ ngx_event_pipe_write_to_downstream(ngx_e
             if (p->out) {
                 cl = p->out;
 
-                if (cl->buf->recycled
-                    && bsize + cl->buf->last - cl->buf->pos > p->busy_size)
-                {
-                    flush = 1;
-                    break;
+                if (cl->buf->recycled) {
+                    ngx_log_error(NGX_LOG_ALERT, p->log, 0,
+                                  "recycled buffer in pipe out chain");
                 }
 
                 p->out = p->out->next;
 
-                ngx_event_pipe_free_shadow_raw_buf(&p->free_raw_bufs, cl->buf);
-
             } else if (!p->cacheable && p->in) {
                 cl = p->in;
 
@@ -596,24 +590,13 @@ ngx_event_pipe_write_to_downstream(ngx_e
                                cl->buf->pos,
                                cl->buf->last - cl->buf->pos);
 
-                if (cl->buf->recycled
-                    && cl->buf->last_shadow
-                    && bsize + cl->buf->last - cl->buf->pos > p->busy_size)
-                {
-                    if (!prev_last_shadow) {
-                        p->in = p->in->next;
-
-                        cl->next = NULL;
-
-                        if (out) {
-                            *ll = cl;
-                        } else {
-                            out = cl;
-                        }
+                if (cl->buf->recycled && prev_last_shadow) {
+                    if (bsize + cl->buf->end - cl->buf->start > p->busy_size) {
+                        flush = 1;
+                        break;
                     }
 
-                    flush = 1;
-                    break;
+                    bsize += cl->buf->end - cl->buf->start;
                 }
 
                 prev_last_shadow = cl->buf->last_shadow;
@@ -624,10 +607,6 @@ ngx_event_pipe_write_to_downstream(ngx_e
                 break;
             }
 
-            if (cl->buf->recycled) {
-                bsize += cl->buf->last - cl->buf->pos;
-            }
-
             cl->next = NULL;
 
             if (out) {
@@ -701,9 +680,10 @@ ngx_event_pipe_write_to_downstream(ngx_e
 static ngx_int_t
 ngx_event_pipe_write_chain_to_temp_file(ngx_event_pipe_t *p)
 {
-    ssize_t       size, bsize;
+    ssize_t       size, bsize, n;
     ngx_buf_t    *b;
-    ngx_chain_t  *cl, *tl, *next, *out, **ll, **last_free, fl;
+    ngx_uint_t    prev_last_shadow;
+    ngx_chain_t  *cl, *tl, *next, *out, **ll, **last_out, **last_free, fl;
 
     if (p->buf_to_file) {
         fl.buf = p->buf_to_file;
@@ -719,6 +699,7 @@ ngx_event_pipe_write_chain_to_temp_file(
         size = 0;
         cl = out;
         ll = NULL;
+        prev_last_shadow = 1;
 
         ngx_log_debug1(NGX_LOG_DEBUG_EVENT, p->log, 0,
                        "pipe offset: %O", p->temp_file->offset);
@@ -726,16 +707,21 @@ ngx_event_pipe_write_chain_to_temp_file(
         do {
             bsize = cl->buf->last - cl->buf->pos;
 
-            ngx_log_debug3(NGX_LOG_DEBUG_EVENT, p->log, 0,
-                           "pipe buf %p, pos %p, size: %z",
-                           cl->buf->start, cl->buf->pos, bsize);
+            ngx_log_debug4(NGX_LOG_DEBUG_EVENT, p->log, 0,
+                           "pipe buf ls:%d %p, pos %p, size: %z",
+                           cl->buf->last_shadow, cl->buf->start,
+                           cl->buf->pos, bsize);
 
-            if ((size + bsize > p->temp_file_write_size)
-               || (p->temp_file->offset + size + bsize > p->max_temp_file_size))
+            if (prev_last_shadow
+                && ((size + bsize > p->temp_file_write_size)
+                    || (p->temp_file->offset + size + bsize
+                        > p->max_temp_file_size)))
             {
                 break;
             }
 
+            prev_last_shadow = cl->buf->last_shadow;
+
             size += bsize;
             ll = &cl->next;
             cl = cl->next;
@@ -762,10 +748,63 @@ ngx_event_pipe_write_chain_to_temp_file(
         p->last_in = &p->in;
     }
 
-    if (ngx_write_chain_to_temp_file(p->temp_file, out) == NGX_ERROR) {
+    n = ngx_write_chain_to_temp_file(p->temp_file, out);
+
+    if (n == NGX_ERROR) {
         return NGX_ABORT;
     }
 
+    if (p->buf_to_file) {
+        p->temp_file->offset = p->buf_to_file->last - p->buf_to_file->pos;
+        n -= p->buf_to_file->last - p->buf_to_file->pos;
+        p->buf_to_file = NULL;
+        out = out->next;
+    }
+
+    if (n > 0) {
+        /* update previous buffer or add new buffer */
+
+        if (p->out) {
+            for (cl = p->out; cl->next; cl = cl->next) { /* void */ }
+
+            b = cl->buf;
+
+            if (b->file_last == p->temp_file->offset) {
+                p->temp_file->offset += n;
+                b->file_last = p->temp_file->offset;
+                goto free;
+            }
+
+            last_out = &cl->next;
+
+        } else {
+            last_out = &p->out;
+        }
+
+        cl = ngx_chain_get_free_buf(p->pool, &p->free);
+        if (cl == NULL) {
+            return NGX_ABORT;
+        }
+
+        b = cl->buf;
+
+        ngx_memzero(b, sizeof(ngx_buf_t));
+
+        b->tag = p->tag;
+
+        b->file = &p->temp_file->file;
+        b->file_pos = p->temp_file->offset;
+        p->temp_file->offset += n;
+        b->file_last = p->temp_file->offset;
+
+        b->in_file = 1;
+        b->temp_file = 1;
+
+        *last_out = cl;
+    }
+
+free:
+
     for (last_free = &p->free_raw_bufs;
          *last_free != NULL;
          last_free = &(*last_free)->next)
@@ -773,31 +812,13 @@ ngx_event_pipe_write_chain_to_temp_file(
         /* void */
     }
 
-    if (p->buf_to_file) {
-        p->temp_file->offset = p->buf_to_file->last - p->buf_to_file->pos;
-        p->buf_to_file = NULL;
-        out = out->next;
-    }
-
     for (cl = out; cl; cl = next) {
         next = cl->next;
-        cl->next = NULL;
+
+        cl->next = p->free;
+        p->free = cl;
 
         b = cl->buf;
-        b->file = &p->temp_file->file;
-        b->file_pos = p->temp_file->offset;
-        p->temp_file->offset += b->last - b->pos;
-        b->file_last = p->temp_file->offset;
-
-        b->in_file = 1;
-        b->temp_file = 1;
-
-        if (p->out) {
-            *p->last_out = cl;
-        } else {
-            p->out = cl;
-        }
-        p->last_out = &cl->next;
 
         if (b->last_shadow) {
 
@@ -913,35 +934,6 @@ ngx_event_pipe_remove_shadow_links(ngx_b
 }
 
 
-static ngx_inline void
-ngx_event_pipe_free_shadow_raw_buf(ngx_chain_t **free, ngx_buf_t *buf)
-{
-    ngx_buf_t    *s;
-    ngx_chain_t  *cl, **ll;
-
-    if (buf->shadow == NULL) {
-        return;
-    }
-
-    for (s = buf->shadow; !s->last_shadow; s = s->shadow) { /* void */ }
-
-    ll = free;
-
-    for (cl = *free; cl; cl = cl->next) {
-        if (cl->buf == s) {
-            *ll = cl->next;
-            break;
-        }
-
-        if (cl->buf->shadow) {
-            break;
-        }
-
-        ll = &cl->next;
-    }
-}
-
-
 ngx_int_t
 ngx_event_pipe_add_free_buf(ngx_event_pipe_t *p, ngx_buf_t *b)
 {