aboutsummaryrefslogtreecommitdiff
path: root/src/core/ngx_buf.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/ngx_buf.c')
-rw-r--r--src/core/ngx_buf.c42
1 files changed, 42 insertions, 0 deletions
diff --git a/src/core/ngx_buf.c b/src/core/ngx_buf.c
index 764b34bf9..00b664458 100644
--- a/src/core/ngx_buf.c
+++ b/src/core/ngx_buf.c
@@ -220,6 +220,48 @@ ngx_chain_update_chains(ngx_pool_t *p, ngx_chain_t **free, ngx_chain_t **busy,
}
+off_t
+ngx_chain_coalesce_file(ngx_chain_t **in, off_t limit)
+{
+ off_t total, size, aligned, fprev;
+ ngx_fd_t fd;
+ ngx_chain_t *cl;
+
+ total = 0;
+
+ cl = *in;
+ fd = cl->buf->file->fd;
+
+ do {
+ size = cl->buf->file_last - cl->buf->file_pos;
+
+ if (size > limit - total) {
+ size = limit - total;
+
+ aligned = (cl->buf->file_pos + size + ngx_pagesize - 1)
+ & ~((off_t) ngx_pagesize - 1);
+
+ if (aligned <= cl->buf->file_last) {
+ size = aligned - cl->buf->file_pos;
+ }
+ }
+
+ total += size;
+ fprev = cl->buf->file_pos + size;
+ cl = cl->next;
+
+ } while (cl
+ && cl->buf->in_file
+ && total < limit
+ && fd == cl->buf->file->fd
+ && fprev == cl->buf->file_pos);
+
+ *in = cl;
+
+ return total;
+}
+
+
ngx_chain_t *
ngx_chain_update_sent(ngx_chain_t *in, off_t sent)
{