summaryrefslogtreecommitdiff
path: root/src/event/ngx_event_pipe.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/event/ngx_event_pipe.c')
-rw-r--r--src/event/ngx_event_pipe.c158
1 files changed, 75 insertions, 83 deletions
diff --git a/src/event/ngx_event_pipe.c b/src/event/ngx_event_pipe.c
index 4f45bb872..c389f2eba 100644
--- 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_downstream(ngx_event_pipe_t *p);
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_event_pipe_t *p)
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_event_pipe_t *p)
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_event_pipe_t *p)
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_event_pipe_t *p)
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(ngx_event_pipe_t *p)
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(ngx_event_pipe_t *p)
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,42 +748,77 @@ ngx_event_pipe_write_chain_to_temp_file(ngx_event_pipe_t *p)
p->last_in = &p->in;
}
- if (ngx_write_chain_to_temp_file(p->temp_file, out) == NGX_ERROR) {
- return NGX_ABORT;
- }
+ n = ngx_write_chain_to_temp_file(p->temp_file, out);
- for (last_free = &p->free_raw_bufs;
- *last_free != NULL;
- last_free = &(*last_free)->next)
- {
- /* void */
+ 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;
}
- for (cl = out; cl; cl = next) {
- next = cl->next;
- cl->next = NULL;
+ 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 += b->last - b->pos;
+ p->temp_file->offset += n;
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;
+ *last_out = cl;
+ }
+
+free:
+
+ for (last_free = &p->free_raw_bufs;
+ *last_free != NULL;
+ last_free = &(*last_free)->next)
+ {
+ /* void */
+ }
+
+ for (cl = out; cl; cl = next) {
+ next = cl->next;
+
+ cl->next = p->free;
+ p->free = cl;
+
+ b = cl->buf;
if (b->last_shadow) {
@@ -913,35 +934,6 @@ 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)
-{
- 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)
{