Mercurial > hg > nginx
comparison src/core/ngx_output_chain.c @ 343:6bdf858bff8c
nginx-0.0.3-2004-05-28-19:49:23 import; rename ngx_hunk_t to ngx_buf_t
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Fri, 28 May 2004 15:49:23 +0000 |
parents | af451db3fe99 |
children | e366ba5db8f8 |
comparison
equal
deleted
inserted
replaced
342:0ee0642af5f1 | 343:6bdf858bff8c |
---|---|
6 | 6 |
7 #define NGX_NONE 1 | 7 #define NGX_NONE 1 |
8 | 8 |
9 | 9 |
10 ngx_inline static int ngx_output_chain_need_to_copy(ngx_output_chain_ctx_t *ctx, | 10 ngx_inline static int ngx_output_chain_need_to_copy(ngx_output_chain_ctx_t *ctx, |
11 ngx_hunk_t *hunk); | 11 ngx_buf_t *buf); |
12 static int ngx_output_chain_copy_hunk(ngx_hunk_t *dst, ngx_hunk_t *src, | 12 static ngx_int_t ngx_output_chain_copy_buf(ngx_buf_t *dst, ngx_buf_t *src, |
13 u_int sendfile); | 13 ngx_uint_t sendfile); |
14 | 14 |
15 | 15 |
16 int ngx_output_chain(ngx_output_chain_ctx_t *ctx, ngx_chain_t *in) | 16 int ngx_output_chain(ngx_output_chain_ctx_t *ctx, ngx_chain_t *in) |
17 { | 17 { |
18 int rc, last; | 18 int rc, last; |
19 size_t size, hsize; | 19 size_t size, bsize; |
20 ngx_chain_t *cl, *out, **last_out; | 20 ngx_chain_t *cl, *out, **last_out; |
21 | 21 |
22 /* | 22 /* |
23 * the short path for the case when the ctx->in chain is empty | 23 * the short path for the case when the ctx->in chain is empty |
24 * and the incoming chain is empty too or it has the single hunk | 24 * and the incoming chain is empty too or it has the single buf |
25 * that does not require the copy | 25 * that does not require the copy |
26 */ | 26 */ |
27 | 27 |
28 if (ctx->in == NULL) { | 28 if (ctx->in == NULL) { |
29 | 29 |
30 if (in == NULL) { | 30 if (in == NULL) { |
31 return ctx->output_filter(ctx->filter_ctx, in); | 31 return ctx->output_filter(ctx->filter_ctx, in); |
32 } | 32 } |
33 | 33 |
34 if (in->next == NULL | 34 if (in->next == NULL |
35 && (!ngx_output_chain_need_to_copy(ctx, in->hunk))) | 35 && (!ngx_output_chain_need_to_copy(ctx, in->buf))) |
36 { | 36 { |
37 return ctx->output_filter(ctx->filter_ctx, in); | 37 return ctx->output_filter(ctx->filter_ctx, in); |
38 } | 38 } |
39 } | 39 } |
40 | 40 |
53 for ( ;; ) { | 53 for ( ;; ) { |
54 | 54 |
55 while (ctx->in) { | 55 while (ctx->in) { |
56 | 56 |
57 /* | 57 /* |
58 * cycle while there are the ctx->in hunks | 58 * cycle while there are the ctx->in bufs |
59 * or there are the free output hunks to copy in | 59 * or there are the free output bufs to copy in |
60 */ | 60 */ |
61 | 61 |
62 if (!ngx_output_chain_need_to_copy(ctx, ctx->in->hunk)) { | 62 if (!ngx_output_chain_need_to_copy(ctx, ctx->in->buf)) { |
63 | 63 |
64 /* move the chain link to the output chain */ | 64 /* move the chain link to the output chain */ |
65 | 65 |
66 cl = ctx->in; | 66 cl = ctx->in; |
67 ctx->in = cl->next; | 67 ctx->in = cl->next; |
71 cl->next = NULL; | 71 cl->next = NULL; |
72 | 72 |
73 continue; | 73 continue; |
74 } | 74 } |
75 | 75 |
76 if (ctx->hunk == NULL) { | 76 if (ctx->buf == NULL) { |
77 | 77 |
78 /* get the free hunk */ | 78 /* get the free buf */ |
79 | 79 |
80 if (ctx->free) { | 80 if (ctx->free) { |
81 ctx->hunk = ctx->free->hunk; | 81 ctx->buf = ctx->free->buf; |
82 ctx->free = ctx->free->next; | 82 ctx->free = ctx->free->next; |
83 | 83 |
84 } else if (out || ctx->hunks == ctx->bufs.num) { | 84 } else if (out || ctx->allocated == ctx->bufs.num) { |
85 | 85 |
86 break; | 86 break; |
87 | 87 |
88 } else { | 88 } else { |
89 | 89 |
90 size = ctx->bufs.size; | 90 size = ctx->bufs.size; |
91 | 91 |
92 if (ctx->in->hunk->type & NGX_HUNK_LAST) { | 92 if (ctx->in->buf->last_buf) { |
93 | 93 |
94 hsize = ngx_hunk_size(ctx->in->hunk); | 94 bsize = ngx_buf_size(ctx->in->buf); |
95 | 95 |
96 if (hsize < ctx->bufs.size) { | 96 if (bsize < ctx->bufs.size) { |
97 | 97 |
98 /* | 98 /* |
99 * allocate small temp hunk for the small last hunk | 99 * allocate small temp buf for the small last buf |
100 * or its small last part | 100 * or its small last part |
101 */ | 101 */ |
102 | 102 |
103 size = hsize; | 103 size = bsize; |
104 | 104 |
105 } else if (ctx->bufs.num == 1 | 105 } else if (ctx->bufs.num == 1 |
106 && (hsize < ctx->bufs.size | 106 && (bsize < ctx->bufs.size |
107 + (ctx->bufs.size >> 2))) | 107 + (ctx->bufs.size >> 2))) |
108 { | 108 { |
109 /* | 109 /* |
110 * allocate a temp hunk that equals | 110 * allocate a temp buf that equals |
111 * to the last hunk if the last hunk size is lesser | 111 * to the last buf if the last buf size is lesser |
112 * than 1.25 of bufs.size and a temp hunk is single | 112 * than 1.25 of bufs.size and a temp buf is single |
113 */ | 113 */ |
114 | 114 |
115 size = hsize; | 115 size = bsize; |
116 } | 116 } |
117 } | 117 } |
118 | 118 |
119 ngx_test_null(ctx->hunk, | 119 if (!(ctx->buf = ngx_create_temp_buf(ctx->pool, size))) { |
120 ngx_create_temp_hunk(ctx->pool, size), | 120 return NGX_ERROR; |
121 NGX_ERROR); | 121 } |
122 ctx->hunk->tag = ctx->tag; | 122 |
123 ctx->hunk->type |= NGX_HUNK_RECYCLED; | 123 ctx->buf->tag = ctx->tag; |
124 ctx->hunks++; | 124 ctx->buf->recycled = 1; |
125 ctx->allocated++; | |
125 } | 126 } |
126 } | 127 } |
127 | 128 |
128 rc = ngx_output_chain_copy_hunk(ctx->hunk, ctx->in->hunk, | 129 rc = ngx_output_chain_copy_buf(ctx->buf, ctx->in->buf, |
129 ctx->sendfile); | 130 ctx->sendfile); |
130 | 131 |
131 if (rc == NGX_ERROR) { | 132 if (rc == NGX_ERROR) { |
132 return rc; | 133 return rc; |
133 } | 134 } |
134 | 135 |
137 break; | 138 break; |
138 } | 139 } |
139 return rc; | 140 return rc; |
140 } | 141 } |
141 | 142 |
142 /* delete the completed hunk from the ctx->in chain */ | 143 /* delete the completed buf from the ctx->in chain */ |
143 | 144 |
144 if (ngx_hunk_size(ctx->in->hunk) == 0) { | 145 if (ngx_buf_size(ctx->in->buf) == 0) { |
145 ctx->in = ctx->in->next; | 146 ctx->in = ctx->in->next; |
146 } | 147 } |
147 | 148 |
148 ngx_alloc_link_and_set_hunk(cl, ctx->hunk, ctx->pool, NGX_ERROR); | 149 ngx_alloc_link_and_set_buf(cl, ctx->buf, ctx->pool, NGX_ERROR); |
149 *last_out = cl; | 150 *last_out = cl; |
150 last_out = &cl->next; | 151 last_out = &cl->next; |
151 ctx->hunk = NULL; | 152 ctx->buf = NULL; |
152 } | 153 } |
153 | 154 |
154 if (out == NULL && last != NGX_NONE) { | 155 if (out == NULL && last != NGX_NONE) { |
155 return last; | 156 return last; |
156 } | 157 } |
166 } | 167 } |
167 } | 168 } |
168 | 169 |
169 | 170 |
170 ngx_inline static int ngx_output_chain_need_to_copy(ngx_output_chain_ctx_t *ctx, | 171 ngx_inline static int ngx_output_chain_need_to_copy(ngx_output_chain_ctx_t *ctx, |
171 ngx_hunk_t *hunk) | 172 ngx_buf_t *buf) |
172 { | 173 { |
173 if (ngx_hunk_special(hunk)) { | 174 if (ngx_buf_special(buf)) { |
174 return 0; | 175 return 0; |
175 } | 176 } |
176 | 177 |
177 if (!ctx->sendfile) { | 178 if (!ctx->sendfile) { |
178 if (!(hunk->type & NGX_HUNK_IN_MEMORY)) { | 179 if (!ngx_buf_in_memory(buf)) { |
179 return 1; | 180 return 1; |
180 } | 181 } |
181 | 182 |
182 hunk->type &= ~NGX_HUNK_FILE; | 183 buf->in_file = 0; |
183 } | 184 } |
184 | 185 |
185 if (ctx->need_in_memory && (!(hunk->type & NGX_HUNK_IN_MEMORY))) { | 186 if (ctx->need_in_memory && !ngx_buf_in_memory(buf)) { |
186 return 1; | 187 return 1; |
187 } | 188 } |
188 | 189 |
189 | 190 if (ctx->need_in_temp && (buf->memory || buf->mmap)) { |
190 if (ctx->need_in_temp && (hunk->type & (NGX_HUNK_MEMORY|NGX_HUNK_MMAP))) { | |
191 return 1; | 191 return 1; |
192 } | 192 } |
193 | 193 |
194 return 0; | 194 return 0; |
195 } | 195 } |
196 | 196 |
197 | 197 |
198 static int ngx_output_chain_copy_hunk(ngx_hunk_t *dst, ngx_hunk_t *src, | 198 static ngx_int_t ngx_output_chain_copy_buf(ngx_buf_t *dst, ngx_buf_t *src, |
199 u_int sendfile) | 199 ngx_uint_t sendfile) |
200 { | 200 { |
201 size_t size; | 201 size_t size; |
202 ssize_t n; | 202 ssize_t n; |
203 | 203 |
204 size = ngx_hunk_size(src); | 204 size = ngx_buf_size(src); |
205 | 205 |
206 if (size > (size_t) (dst->end - dst->pos)) { | 206 if (size > (size_t) (dst->end - dst->pos)) { |
207 size = dst->end - dst->pos; | 207 size = dst->end - dst->pos; |
208 } | 208 } |
209 | 209 |
210 if (src->type & NGX_HUNK_IN_MEMORY) { | 210 if (ngx_buf_in_memory(src)) { |
211 ngx_memcpy(dst->pos, src->pos, size); | 211 ngx_memcpy(dst->pos, src->pos, size); |
212 src->pos += size; | 212 src->pos += size; |
213 dst->last += size; | 213 dst->last += size; |
214 | 214 |
215 if (src->type & NGX_HUNK_FILE) { | 215 if (src->in_file) { |
216 src->file_pos += size; | 216 src->file_pos += size; |
217 } | 217 } |
218 | 218 |
219 if ((src->type & NGX_HUNK_LAST) && src->pos == src->last) { | 219 if (src->last_buf && src->pos == src->last) { |
220 dst->type |= NGX_HUNK_LAST; | 220 dst->last_buf = 1; |
221 } | 221 } |
222 | 222 |
223 } else { | 223 } else { |
224 n = ngx_read_file(src->file, dst->pos, size, src->file_pos); | 224 n = ngx_read_file(src->file, dst->pos, size, src->file_pos); |
225 | 225 |
244 | 244 |
245 src->file_pos += n; | 245 src->file_pos += n; |
246 dst->last += n; | 246 dst->last += n; |
247 | 247 |
248 if (!sendfile) { | 248 if (!sendfile) { |
249 dst->type &= ~NGX_HUNK_FILE; | 249 dst->in_file = 0; |
250 } | 250 } |
251 | 251 |
252 if ((src->type & NGX_HUNK_LAST) && src->file_pos == src->file_last) { | 252 if (src->last_buf && src->file_pos == src->file_last) { |
253 dst->type |= NGX_HUNK_LAST; | 253 dst->last_buf = 1; |
254 } | 254 } |
255 } | 255 } |
256 | 256 |
257 return NGX_OK; | 257 return NGX_OK; |
258 } | 258 } |
259 | 259 |
260 | 260 |
261 int ngx_chain_writer(void *data, ngx_chain_t *in) | 261 ngx_int_t ngx_chain_writer(void *data, ngx_chain_t *in) |
262 { | 262 { |
263 ngx_chain_writer_ctx_t *ctx = data; | 263 ngx_chain_writer_ctx_t *ctx = data; |
264 | 264 |
265 ngx_chain_t *cl; | 265 ngx_chain_t *cl; |
266 | 266 |
267 | 267 |
268 for (/* void */; in; in = in->next) { | 268 for (/* void */; in; in = in->next) { |
269 ngx_alloc_link_and_set_hunk(cl, in->hunk, ctx->pool, NGX_ERROR); | 269 ngx_alloc_link_and_set_buf(cl, in->buf, ctx->pool, NGX_ERROR); |
270 *ctx->last = cl; | 270 *ctx->last = cl; |
271 ctx->last = &cl->next; | 271 ctx->last = &cl->next; |
272 } | 272 } |
273 | 273 |
274 ngx_log_debug1(NGX_LOG_DEBUG_CORE, ctx->connection->log, 0, | 274 ngx_log_debug1(NGX_LOG_DEBUG_CORE, ctx->connection->log, 0, |