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