split ngx_output_chain()
Igor Sysoev
13 years ago
20 | 20 | ngx_output_chain_need_to_copy(ngx_output_chain_ctx_t *ctx, ngx_buf_t *buf); |
21 | 21 | static ngx_int_t ngx_output_chain_add_copy(ngx_pool_t *pool, |
22 | 22 | ngx_chain_t **chain, ngx_chain_t *in); |
23 | static ngx_int_t ngx_output_chain_get_buf(ngx_output_chain_ctx_t *ctx, | |
24 | off_t bsize); | |
23 | 25 | static ngx_int_t ngx_output_chain_copy_buf(ngx_buf_t *dst, ngx_buf_t *src, |
24 | 26 | ngx_uint_t sendfile); |
25 | 27 | |
28 | 30 | ngx_output_chain(ngx_output_chain_ctx_t *ctx, ngx_chain_t *in) |
29 | 31 | { |
30 | 32 | off_t bsize; |
31 | size_t size; | |
32 | 33 | ngx_int_t rc, last; |
33 | ngx_uint_t recycled; | |
34 | ngx_buf_t *b; | |
35 | 34 | ngx_chain_t *cl, *out, **last_out; |
36 | 35 | |
37 | 36 | if (ctx->in == NULL && ctx->busy == NULL) { |
129 | 128 | |
130 | 129 | break; |
131 | 130 | |
132 | } else { | |
133 | ||
134 | size = ctx->bufs.size; | |
135 | recycled = 1; | |
136 | ||
137 | if (ctx->in->buf->last_in_chain) { | |
138 | ||
139 | if (bsize < (off_t) ctx->bufs.size) { | |
140 | ||
141 | /* | |
142 | * allocate small temp buf for the small last buf | |
143 | * or its small last part | |
144 | */ | |
145 | ||
146 | size = (size_t) bsize; | |
147 | recycled = 0; | |
148 | ||
149 | } else if (ctx->bufs.num == 1 | |
150 | && (bsize < (off_t) (ctx->bufs.size | |
151 | + (ctx->bufs.size >> 2)))) | |
152 | { | |
153 | /* | |
154 | * allocate a temp buf that equals | |
155 | * to the last buf if the last buf size is lesser | |
156 | * than 1.25 of bufs.size and a temp buf is single | |
157 | */ | |
158 | ||
159 | size = (size_t) bsize; | |
160 | recycled = 0; | |
161 | } | |
162 | } | |
163 | ||
164 | b = ngx_calloc_buf(ctx->pool); | |
165 | if (b == NULL) { | |
166 | return NGX_ERROR; | |
167 | } | |
168 | ||
169 | /* | |
170 | * allocate block aligned to a disk sector size | |
171 | * to enable O_DIRECT | |
172 | */ | |
173 | ||
174 | b->start = ngx_pmemalign(ctx->pool, size, 512); | |
175 | if (b->start == NULL) { | |
176 | return NGX_ERROR; | |
177 | } | |
178 | ||
179 | b->pos = b->start; | |
180 | b->last = b->start; | |
181 | b->end = b->last + size; | |
182 | b->temporary = 1; | |
183 | b->tag = ctx->tag; | |
184 | b->recycled = recycled; | |
185 | ||
186 | ctx->buf = b; | |
187 | ctx->allocated++; | |
131 | } else if (ngx_output_chain_get_buf(ctx, bsize) != NGX_OK) { | |
132 | return NGX_ERROR; | |
188 | 133 | } |
189 | 134 | } |
190 | 135 | |
351 | 296 | |
352 | 297 | |
353 | 298 | static ngx_int_t |
299 | ngx_output_chain_get_buf(ngx_output_chain_ctx_t *ctx, off_t bsize) | |
300 | { | |
301 | size_t size; | |
302 | ngx_buf_t *b; | |
303 | ngx_uint_t recycled; | |
304 | ||
305 | size = ctx->bufs.size; | |
306 | recycled = 1; | |
307 | ||
308 | if (ctx->in->buf->last_in_chain) { | |
309 | ||
310 | if (bsize < (off_t) size) { | |
311 | ||
312 | /* | |
313 | * allocate a small temp buf for a small last buf | |
314 | * or its small last part | |
315 | */ | |
316 | ||
317 | size = (size_t) bsize; | |
318 | recycled = 0; | |
319 | ||
320 | } else if (ctx->bufs.num == 1 && (bsize < (off_t) (size + size / 4))) { | |
321 | ||
322 | /* | |
323 | * allocate a temp buf that equals to a last buf, if the last buf | |
324 | * size is lesser than 1.25 of bufs.size and the temp buf is single | |
325 | */ | |
326 | ||
327 | size = (size_t) bsize; | |
328 | recycled = 0; | |
329 | } | |
330 | } | |
331 | ||
332 | b = ngx_calloc_buf(ctx->pool); | |
333 | if (b == NULL) { | |
334 | return NGX_ERROR; | |
335 | } | |
336 | ||
337 | /* allocate block aligned to a disk sector size to enable O_DIRECT */ | |
338 | ||
339 | b->start = ngx_pmemalign(ctx->pool, size, 512); | |
340 | if (b->start == NULL) { | |
341 | return NGX_ERROR; | |
342 | } | |
343 | ||
344 | b->pos = b->start; | |
345 | b->last = b->start; | |
346 | b->end = b->last + size; | |
347 | b->temporary = 1; | |
348 | b->tag = ctx->tag; | |
349 | b->recycled = recycled; | |
350 | ||
351 | ctx->buf = b; | |
352 | ctx->allocated++; | |
353 | ||
354 | return NGX_OK; | |
355 | } | |
356 | ||
357 | ||
358 | static ngx_int_t | |
354 | 359 | ngx_output_chain_copy_buf(ngx_buf_t *dst, ngx_buf_t *src, ngx_uint_t sendfile) |
355 | 360 | { |
356 | 361 | off_t size; |