Mercurial > hg > nginx
comparison src/event/ngx_event_proxy.c @ 148:5afee0074707
nginx-0.0.1-2003-10-17-00:19:16 import
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Thu, 16 Oct 2003 20:19:16 +0000 |
parents | be71fca7f9d7 |
children | 86404ba5c517 |
comparison
equal
deleted
inserted
replaced
147:be71fca7f9d7 | 148:5afee0074707 |
---|---|
2 #include <ngx_config.h> | 2 #include <ngx_config.h> |
3 #include <ngx_core.h> | 3 #include <ngx_core.h> |
4 #include <ngx_event.h> | 4 #include <ngx_event.h> |
5 #include <ngx_event_proxy.h> | 5 #include <ngx_event_proxy.h> |
6 | 6 |
7 static int ngx_event_proxy_write_chain_to_temp_file(ngx_event_proxy_t *p); | |
8 ngx_inline static void ngx_remove_shadow_links(ngx_hunk_t *hunk); | |
9 ngx_inline static void ngx_remove_shadow_free_raw_hunk(ngx_chain_t **free, | |
10 ngx_hunk_t *h); | |
11 ngx_inline static void ngx_add_after_partially_filled_hunk(ngx_chain_t **chain, | |
12 ngx_chain_t *ce); | |
13 | |
7 | 14 |
8 int ngx_event_proxy_read_upstream(ngx_event_proxy_t *p) | 15 int ngx_event_proxy_read_upstream(ngx_event_proxy_t *p) |
9 { | 16 { |
10 int n, rc, size; | 17 int n, rc, size; |
11 ngx_hunk_t *h, *nh; | 18 ngx_hunk_t *h; |
12 ngx_chain_t *chain, *rest, *ce, *next; | 19 ngx_chain_t *chain, *ce, *te; |
13 | |
14 rest = NULL; | |
15 | 20 |
16 p->upstream_level++; | 21 p->upstream_level++; |
17 | 22 |
18 ngx_log_debug(p->log, "read upstream"); | 23 ngx_log_debug(p->log, "read upstream: %d" _ p->upstream->read->ready); |
19 | 24 |
20 for ( ;; ) { | 25 while (p->preread_hunks |
21 | 26 || (p->upstream->read->ready && !p->upstream_done)) |
27 { | |
22 if (p->preread_hunks) { | 28 if (p->preread_hunks) { |
23 | 29 |
24 /* use the pre-read hunks if they exist */ | 30 /* use the pre-read hunks if they exist */ |
25 | 31 |
26 chain = p->preread_hunks; | 32 chain = p->preread_hunks; |
27 p->preread_hunks = NULL; | 33 p->preread_hunks = NULL; |
28 n = p->preread_size; | 34 n = p->preread_size; |
29 | 35 |
30 ngx_log_debug(p->log, "preread: %d" _ n); | 36 ngx_log_debug(p->log, "preread: %d" _ n); |
31 | 37 |
32 } else { | 38 } else { |
33 | 39 |
34 #if (HAVE_KQUEUE) | 40 #if (HAVE_KQUEUE) |
35 | 41 |
44 if (p->upstream->read->error) { | 50 if (p->upstream->read->error) { |
45 ngx_log_error(NGX_LOG_ERR, p->log, p->upstream->read->error, | 51 ngx_log_error(NGX_LOG_ERR, p->log, p->upstream->read->error, |
46 "readv() failed"); | 52 "readv() failed"); |
47 p->upstream_error = 1; | 53 p->upstream_error = 1; |
48 | 54 |
55 break; | |
56 | |
49 } else if (p->upstream->read->eof | 57 } else if (p->upstream->read->eof |
50 && p->upstream->read->available == 0) { | 58 && p->upstream->read->available == 0) { |
51 p->upstream_eof = 1; | 59 p->upstream_eof = 1; |
60 | |
61 break; | |
52 } | 62 } |
53 | |
54 if ((p->upstream_eof || p->upstream_error) | |
55 && p->free_raw_hunk) | |
56 { | |
57 if (p->input_filter(p->input_data, p->free_raw_hunk->hunk) | |
58 == NGX_ERROR) { | |
59 return NGX_ABORT; | |
60 } | |
61 | |
62 /* TODO: p->free_raw_hunk->next can be free()ed */ | |
63 p->free_raw_hunk = p->free_raw_hunk->next; | |
64 } | |
65 | |
66 break; | |
67 } | 63 } |
68 #endif | 64 #endif |
69 | 65 |
70 if (p->free_raw_hunks) { | 66 if (p->free_raw_hunks) { |
71 | 67 |
72 /* use the free hunks if they exist */ | 68 /* use the free hunks if they exist */ |
73 | 69 |
74 chain = p->free_raw_hunks; | 70 chain = p->free_raw_hunks; |
75 p->free_raw_hunks = NULL; | 71 p->free_raw_hunks = NULL; |
76 | 72 |
77 ngx_log_debug(p->log, "free hunk: %08X:%d" _ chain->hunk _ | |
78 chain->hunk->end - chain->hunk->last); | |
79 | |
80 } else if (p->hunks < p->bufs.num) { | 73 } else if (p->hunks < p->bufs.num) { |
81 | 74 |
82 /* allocate a new hunk if it's still allowed */ | 75 /* allocate a new hunk if it's still allowed */ |
83 | 76 |
84 ngx_test_null(h, ngx_create_temp_hunk(p->pool, | 77 ngx_test_null(h, ngx_create_temp_hunk(p->pool, |
85 p->bufs.size, 20, 20); | 78 p->bufs.size, 0, 0), |
86 NGX_ABORT); | 79 NGX_ABORT); |
87 p->hunks++; | 80 p->hunks++; |
88 | 81 |
89 ngx_alloc_ce_and_set_hunk(te, h, p->pool, NGX_ABORT); | 82 ngx_alloc_ce_and_set_hunk(te, h, p->pool, NGX_ABORT); |
90 chain = te; | 83 chain = te; |
91 | |
92 ngx_log_debug(p->log, "new hunk: %08X" _ chain->hunk); | |
93 | 84 |
94 } else if (!p->cachable && p->downstream->write->ready) { | 85 } else if (!p->cachable && p->downstream->write->ready) { |
95 | 86 |
96 /* | 87 /* |
97 * If the hunks are not needed to be saved in a cache and | 88 * If the hunks are not needed to be saved in a cache and |
98 * a downstream is ready then write the hunks to a downstream. | 89 * a downstream is ready then write the hunks to a downstream. |
99 */ | 90 */ |
100 | 91 |
101 ngx_log_debug(p->log, "downstream ready"); | 92 ngx_log_debug(p->log, "downstream ready"); |
102 | 93 |
103 break; | 94 break; |
104 | 95 |
105 } else if (p->temp_offset < p->max_temp_file_size) { | 96 } else if (p->temp_offset < p->max_temp_file_size) { |
106 | 97 |
109 * to a temporary file, and add them to a r->out chain. | 100 * to a temporary file, and add them to a r->out chain. |
110 */ | 101 */ |
111 | 102 |
112 rc = ngx_event_proxy_write_chain_to_temp_file(p); | 103 rc = ngx_event_proxy_write_chain_to_temp_file(p); |
113 | 104 |
114 ngx_log_debug(p->log, "temp offset: %d" _ p->temp_offset); | 105 ngx_log_debug(p->log, "temp offset: %d" _ p->temp_offset); |
115 | 106 |
116 if (rc == NGX_AGAIN) { | 107 if (rc == NGX_AGAIN) { |
117 if (ngx_event_flags & NGX_USE_LEVEL_EVENT | 108 if (ngx_event_flags & NGX_USE_LEVEL_EVENT |
118 && p->upstream->read->active | 109 && p->upstream->read->active |
119 && p->upstream->read->ready) | 110 && p->upstream->read->ready) |
131 } | 122 } |
132 | 123 |
133 chain = p->free_raw_hunks; | 124 chain = p->free_raw_hunks; |
134 p->free_raw_hunks = NULL; | 125 p->free_raw_hunks = NULL; |
135 | 126 |
136 ngx_log_debug(p->log, "new file hunk: %08X:%d" _ chain->hunk _ | |
137 chain->hunk->end - chain->hunk->last); | |
138 | |
139 } else { | 127 } else { |
140 | 128 |
141 /* if there're no hunks to read in then disable a level event */ | 129 /* if there're no hunks to read in then disable a level event */ |
142 | 130 |
143 ngx_log_debug(p->log, "no hunks to read in"); | 131 ngx_log_debug(p->log, "no hunks to read in"); |
144 | 132 |
145 break; | 133 break; |
146 } | 134 } |
147 | 135 |
148 n = ngx_recv_chain(p->upstream, chain); | 136 n = ngx_recv_chain(p->upstream, chain); |
149 | 137 |
150 ngx_log_debug(p->log, "recv_chain: %d" _ n); | 138 ngx_log_debug(p->log, "recv_chain: %d" _ n); |
151 | 139 |
152 if (n == NGX_ERROR) { | 140 if (n == NGX_ERROR) { |
153 p->upstream_error = 1; | 141 p->upstream_error = 1; |
154 return NGX_ERROR; | 142 return NGX_ERROR; |
155 } | 143 } |
157 if (n == NGX_AGAIN) { | 145 if (n == NGX_AGAIN) { |
158 break; | 146 break; |
159 } | 147 } |
160 | 148 |
161 if (n == 0) { | 149 if (n == 0) { |
162 THINK | 150 p->free_raw_hunks = chain; |
163 if (chain->hunk->shadow == NULL) { | |
164 p->free_hunks = chain; | |
165 } | |
166 p->upstream_eof = 1; | 151 p->upstream_eof = 1; |
167 | 152 |
168 break; | 153 break; |
169 } | 154 } |
170 | 155 |
171 } | 156 } |
172 | 157 |
173 for (ce = chain; ce && n > 0; ce = ce->next) { | 158 for (ce = chain; ce && n > 0; ce = ce->next) { |
159 | |
160 ngx_remove_shadow_links(ce->hunk); | |
174 | 161 |
175 size = ce->hunk->end - ce->hunk->last; | 162 size = ce->hunk->end - ce->hunk->last; |
176 | 163 |
177 if (n >= size) { | 164 if (n >= size) { |
178 ce->hunk->last = ce->hunk->end; | 165 ce->hunk->last = ce->hunk->end; |
179 | 166 |
180 if (p->input_filter(p->input_data, ce->hunk) == NGX_ERROR) { | 167 if (p->input_filter(p, ce->hunk) == NGX_ERROR) { |
181 return NGX_ABORT; | 168 return NGX_ABORT; |
182 } | 169 } |
183 | 170 |
184 n -= size; | 171 n -= size; |
185 | 172 |
186 } else if (p->upstream_eof || p->upstream_error) { | 173 chain = ce->next; |
187 | |
188 if (p->input_filter(p->input_data, ce->hunk) == NGX_ERROR) { | |
189 return NGX_ABORT; | |
190 } | |
191 | 174 |
192 } else { | 175 } else { |
193 ce->hunk->last += n; | 176 ce->hunk->last += n; |
194 n = 0; | 177 n = 0; |
195 } | 178 } |
196 | 179 } |
197 | 180 |
198 | 181 p->free_raw_hunks = chain; |
199 | 182 } |
200 | 183 |
201 | 184 if ((p->upstream_eof || p->upstream_error) && p->free_raw_hunks) { |
202 | 185 if (p->input_filter(p, p->free_raw_hunks->hunk) == NGX_ERROR) { |
203 | |
204 next = ce->next; | |
205 ce->next = NULL; | |
206 | |
207 if (ce->hunk->shadow) { | |
208 for (h = ce->hunk->shadow; | |
209 (h->type & NGX_HUNK_LAST_SHADOW) == 0; | |
210 h = nh) | |
211 { | |
212 nh = h->shadow; | |
213 h->shadow = NULL; | |
214 h->type &= ~(NGX_HUNK_TEMP | |
215 |NGX_HUNK_IN_MEMORY | |
216 |NGX_HUNK_RECYCLED); | |
217 } | |
218 | |
219 h->shadow = NULL; | |
220 h->type &= ~(NGX_HUNK_TEMP | |
221 |NGX_HUNK_IN_MEMORY | |
222 |NGX_HUNK_RECYCLED | |
223 |NGX_HUNK_LAST_SHADOW); | |
224 ce->hunk->shadow = NULL; | |
225 } | |
226 | |
227 size = ce->hunk->end - ce->hunk->last; | |
228 | |
229 if (n >= size) { | |
230 ce->hunk->last = ce->hunk->end; | |
231 | |
232 if (p->read_hunks) { | |
233 p->last_read_hunk->next = ce; | |
234 | |
235 } else { | |
236 p->read_hunks = ce; | |
237 } | |
238 | |
239 p->last_read_hunk = ce; | |
240 | |
241 n -= size; | |
242 | |
243 } else { | |
244 ce->hunk->last += n; | |
245 p->free_hunks = ce; | |
246 | |
247 n = 0; | |
248 } | |
249 } | |
250 | |
251 if (chain == p->free_hunks) { | |
252 chain = NULL; | |
253 } | |
254 | |
255 /* | |
256 * the input filter i.e. that moves HTTP/1.1 chunks | |
257 * from a read chain to an incoming chain | |
258 */ | |
259 | |
260 if (p->input_filter(p, chain) == NGX_ERROR) { | |
261 return NGX_ABORT; | 186 return NGX_ABORT; |
262 } | 187 } |
263 | 188 |
264 ngx_log_debug(p->log, "rest chain: %08X" _ ce); | 189 /* TODO: p->free_raw_hunk->next can be free()ed */ |
265 | 190 p->free_raw_hunks = p->free_raw_hunks->next; |
266 /* | |
267 * if the rest hunks are file hunks then move them to a file chain | |
268 * otherwise add them to a free chain | |
269 */ | |
270 | |
271 if (rest) { | |
272 if (rest->hunk->shadow) { | |
273 p->file_hunks = rest; | |
274 | |
275 } else { | |
276 if (p->free_hunks) { | |
277 p->free_hunks->next = rest; | |
278 | |
279 } else { | |
280 p->free_hunks = rest; | |
281 } | |
282 } | |
283 | |
284 break; | |
285 } | |
286 } | |
287 | |
288 ngx_log_debug(p->log, "eof: %d" _ p->upstream_eof); | |
289 | |
290 /* | |
291 * if there's the end of upstream response then move | |
292 * the partially filled hunk from a free chain to an incoming chain | |
293 */ | |
294 | |
295 if (p->upstream_eof) { | |
296 if (p->free_hunks | |
297 && p->free_hunks->hunk->pos < p->free_hunks->hunk->last) | |
298 { | |
299 | |
300 #if (NGX_EVENT_COPY_FILTER) | |
301 | |
302 if (p->input_filter(p, NULL) == NGX_ERROR) { | |
303 return NGX_ABORT; | |
304 } | |
305 #else | |
306 | |
307 if (p->input_filter) { | |
308 if (p->input_filter(p, NULL) == NGX_ERROR) { | |
309 return NGX_ABORT; | |
310 } | |
311 | |
312 } else { | |
313 ce = p->free_hunks; | |
314 | |
315 if (p->in_hunks) { | |
316 p->last_in_hunk->next = ce; | |
317 | |
318 } else { | |
319 p->in_hunks = ce; | |
320 } | |
321 | |
322 p->last_in_hunk = ce; | |
323 } | |
324 | |
325 p->free_hunks = ce->next; | |
326 ce->next = NULL; | |
327 | |
328 #endif /* NGX_EVENT_COPY_FILTER */ | |
329 } | |
330 | |
331 #if 0 | |
332 /* free the unneeded hunks */ | |
333 | |
334 for (ce = p->free_hunks; ce; ce = ce->next) { | |
335 ngx_free_hunk(p->pool, ce->hunk); | |
336 } | |
337 #endif | |
338 | |
339 if (p->in_hunks) { | |
340 p->last_in_hunk->hunk->type |= NGX_HUNK_LAST; | |
341 | |
342 } else if (p->out_hunks) { | |
343 p->last_out_hunk->hunk->type |= NGX_HUNK_LAST; | |
344 } | |
345 } | 191 } |
346 | 192 |
347 if (p->cachable) { | 193 if (p->cachable) { |
348 if (p->in_hunks) { | 194 if (p->in) { |
349 rc = ngx_event_proxy_write_chain_to_temp_file(p); | 195 rc = ngx_event_proxy_write_chain_to_temp_file(p); |
350 | 196 |
351 if (rc != NGX_OK) { | 197 if (rc != NGX_OK) { |
352 return rc; | 198 return rc; |
353 } | 199 } |
354 } | 200 } |
355 | 201 |
356 if (p->out_hunks && p->downstream->write->ready) { | 202 if (p->out && p->downstream->write->ready) { |
357 if (ngx_event_proxy_write_to_downstream(p) == NGX_ABORT) { | 203 if (ngx_event_proxy_write_to_downstream(p) == NGX_ABORT) { |
358 return NGX_ABORT; | 204 return NGX_ABORT; |
359 } | 205 } |
360 } | 206 } |
361 | 207 |
362 } else if ((p->out_hunks || p->in_hunks) && p->downstream->write->ready) { | 208 } else if ((p->out || p->in) && p->downstream->write->ready) { |
363 if (ngx_event_proxy_write_to_downstream(p) == NGX_ABORT) { | 209 if (ngx_event_proxy_write_to_downstream(p) == NGX_ABORT) { |
364 return NGX_ABORT; | 210 return NGX_ABORT; |
365 } | 211 } |
366 } | 212 } |
367 | 213 |
373 if (ngx_handle_read_event(p->upstream->read) == NGX_ERROR) { | 219 if (ngx_handle_read_event(p->upstream->read) == NGX_ERROR) { |
374 return NGX_ABORT; | 220 return NGX_ABORT; |
375 } | 221 } |
376 } | 222 } |
377 | 223 |
378 if (p->upstream_eof) { | 224 return NGX_OK; |
379 return NGX_OK; | |
380 | |
381 } else { | |
382 return NGX_AGAIN; | |
383 } | |
384 } | 225 } |
385 | 226 |
386 | 227 |
387 int ngx_event_proxy_write_to_downstream(ngx_event_proxy_t *p) | 228 int ngx_event_proxy_write_to_downstream(ngx_event_proxy_t *p) |
388 { | 229 { |
389 ngx_chain_t *out, *ce; | 230 int rc; |
231 ngx_hunk_t *h; | |
232 ngx_chain_t *out, *ce, *te; | |
390 | 233 |
391 while (p->downstream->write->ready) { | 234 while (p->downstream->write->ready) { |
392 | 235 |
393 if (p->out) { | 236 if (p->out) { |
394 out = p->out; | 237 out = p->out; |
395 | 238 |
396 if (p->busy_len + ngx_hunk_size(out->hunk)) > p->max_busy_len) { | 239 if (p->busy_len + ngx_hunk_size(out->hunk) > p->max_busy_len) { |
397 break; | 240 break; |
398 } | 241 } |
399 | 242 |
400 p->out = p->out->next; | 243 p->out = p->out->next; |
401 ngx_remove_shadow_free_raw_hunk(&p->free_raw_hunks, out->hunk); | 244 ngx_remove_shadow_free_raw_hunk(&p->free_raw_hunks, out->hunk); |
402 | 245 |
403 } else if (!p->cachable && p->in) { | 246 } else if (!p->cachable && p->in) { |
404 out = p->in; | 247 out = p->in; |
405 | 248 |
406 if (p->busy_len + ngx_hunk_size(out->hunk)) > p->max_busy_len) { | 249 if (p->busy_len + ngx_hunk_size(out->hunk) > p->max_busy_len) { |
407 break; | 250 break; |
408 } | 251 } |
409 | 252 |
410 p->in = p->in->next; | 253 p->in = p->in->next; |
411 | 254 |
413 break; | 256 break; |
414 } | 257 } |
415 | 258 |
416 out->next = NULL; | 259 out->next = NULL; |
417 | 260 |
418 rc = p->output_filter(p->output_data, out->hunk); | 261 rc = p->output_filter(p->output_ctx, out->hunk); |
419 | 262 |
420 ngx_chain_update_chains(p->free, p->busy, out); | 263 ngx_chain_update_chains(&p->free, &p->busy, &out); |
421 | 264 |
422 /* calculate p->busy_len */ | 265 /* calculate p->busy_len */ |
423 | 266 |
424 p->busy_len = 0; | 267 p->busy_len = 0; |
425 for (ce = p->busy; ce; ce = ce->next) { | 268 for (ce = p->busy; ce; ce = ce->next) { |
433 h = ce->hunk->shadow; | 276 h = ce->hunk->shadow; |
434 /* THINK NEEDED ??? */ h->pos = h->last = h->start; | 277 /* THINK NEEDED ??? */ h->pos = h->last = h->start; |
435 h->shadow = NULL; | 278 h->shadow = NULL; |
436 ngx_alloc_ce_and_set_hunk(te, ce->hunk->shadow, p->pool, | 279 ngx_alloc_ce_and_set_hunk(te, ce->hunk->shadow, p->pool, |
437 NGX_ABORT); | 280 NGX_ABORT); |
438 ngx_add_after_partially_filled_hunk(p->free_raw_hunks, te); | 281 ngx_add_after_partially_filled_hunk(&p->free_raw_hunks, te); |
439 | 282 |
440 ce->hunk->type &= ~NGX_HUNK_LAST_SHADOW; | 283 ce->hunk->type &= ~NGX_HUNK_LAST_SHADOW; |
441 } | 284 } |
442 ce->hunk->shadow = NULL; | 285 ce->hunk->shadow = NULL; |
443 } | 286 } |
444 | 287 |
445 if (p->upstream.read->ready) | 288 if (p->upstream->read->ready) { |
446 if (ngx_event_proxy_read_upstream(p) == NGX_ERROR) { | 289 if (ngx_event_proxy_read_upstream(p) == NGX_ERROR) { |
447 return NGX_ABORT; | 290 return NGX_ABORT; |
448 } | 291 } |
449 } | 292 } |
450 } | 293 } |
451 | 294 |
452 if (p->downstream_level == 0) { | 295 if (p->downstream_level == 0) { |
453 if (ngx_handler_write_event(p->downstream->write) == NGX_ERROR) { | 296 if (ngx_handle_write_event(p->downstream->write, |
297 /* TODO: lowat */ 0) == NGX_ERROR) { | |
454 return NGX_ABORT; | 298 return NGX_ABORT; |
455 } | 299 } |
456 } | 300 } |
457 | 301 |
458 if (p->upstream_done && p->in == NULL && p->out == NULL) { | 302 if (p->upstream_done && p->in == NULL && p->out == NULL) { |
461 | 305 |
462 return NGX_OK; | 306 return NGX_OK; |
463 } | 307 } |
464 | 308 |
465 | 309 |
466 int ngx_event_proxy_write_chain_to_temp_file(ngx_event_proxy_t *p) | 310 static int ngx_event_proxy_write_chain_to_temp_file(ngx_event_proxy_t *p) |
467 { | 311 { |
468 int rc, size; | 312 int rc, size; |
469 ngx_hunk_t *h; | 313 ngx_hunk_t *h; |
470 ngx_chain_t *entry, *next, *saved_in, *saved_read; | 314 ngx_chain_t *ce, *next, *in, **last; |
471 | 315 |
472 ngx_log_debug(p->log, "write to file"); | 316 ngx_log_debug(p->log, "write to file"); |
473 | 317 |
474 if (p->temp_file->fd == NGX_INVALID_FILE) { | 318 if (p->temp_file->fd == NGX_INVALID_FILE) { |
475 rc = ngx_create_temp_file(p->temp_file, p->temp_path, p->pool, | 319 rc = ngx_create_temp_file(p->temp_file, p->temp_path, p->pool, |
476 p->cachable); | 320 p->cachable); |
477 | 321 |
481 | 325 |
482 if (rc == NGX_AGAIN) { | 326 if (rc == NGX_AGAIN) { |
483 return NGX_AGAIN; | 327 return NGX_AGAIN; |
484 } | 328 } |
485 | 329 |
486 if (p->cachable == 0 && p->temp_file_warn) { | 330 if (!p->cachable && p->temp_file_warn) { |
487 ngx_log_error(NGX_LOG_WARN, p->log, 0, p->temp_file_warn); | 331 ngx_log_error(NGX_LOG_WARN, p->log, 0, p->temp_file_warn); |
488 } | 332 } |
489 } | 333 } |
490 | 334 |
491 if (p->cachable == 0) { | 335 if (!p->cachable) { |
492 | 336 |
493 entry = p->read_hunks; | |
494 size = 0; | 337 size = 0; |
338 ce = p->in; | |
495 | 339 |
496 do { | 340 do { |
497 size += entry->hunk->last - entry->hunk->pos; | 341 size += ce->hunk->last - ce->hunk->pos; |
498 if (size >= p->temp_file_write_size) { | 342 if (size >= p->temp_file_write_size) { |
499 break; | 343 break; |
500 } | 344 } |
501 entry = entry->next; | 345 ce = ce->next; |
502 | 346 |
503 } while (entry); | 347 } while (ce); |
504 | 348 |
505 saved_read = entry->next; | 349 in = ce->next; |
506 entry->next = NULL; | 350 last = &ce->next; |
507 | 351 ce->next = NULL; |
508 if (saved_read) { | |
509 for (entry = p->in_hunks; entry->next; entry = entry->next) { | |
510 if (entry->next->hunk->shadow == saved_read->hunk) { | |
511 break; | |
512 } | |
513 } | |
514 saved_in = entry->next; | |
515 entry->next = NULL; | |
516 | |
517 } else { | |
518 saved_in = NULL; | |
519 } | |
520 | 352 |
521 } else { | 353 } else { |
522 saved_read = NULL; | 354 in = NULL; |
523 saved_in = NULL; | 355 last = &p->in; |
524 } | 356 } |
525 | 357 |
526 if (ngx_write_chain_to_file(p->temp_file, p->in_hunks, p->temp_offset, | 358 if (ngx_write_chain_to_file(p->temp_file, p->in, p->temp_offset, |
527 p->pool) == NGX_ERROR) { | 359 p->pool) == NGX_ERROR) { |
528 return NGX_ABORT; | 360 return NGX_ABORT; |
529 } | 361 } |
530 | 362 |
531 for (entry = p->in_hunks; entry; entry = next) { | 363 for (ce = p->in; ce; ce = next) { |
532 next = entry->next; | 364 next = ce->next; |
533 entry->next = NULL; | 365 ce->next = NULL; |
534 | 366 |
535 h = entry->hunk; | 367 h = ce->hunk; |
536 h->type |= NGX_HUNK_FILE; | 368 h->type |= NGX_HUNK_FILE; |
537 h->file = p->temp_file; | 369 h->file = p->temp_file; |
538 h->file_pos = p->temp_offset; | 370 h->file_pos = p->temp_offset; |
539 p->temp_offset += h->last - h->pos; | 371 p->temp_offset += h->last - h->pos; |
540 h->file_last = p->temp_offset; | 372 h->file_last = p->temp_offset; |
541 | 373 |
542 ngx_log_debug(p->log, "event proxy file hunk: %08X:%08X" _ h _ h->shadow); | |
543 | |
544 if (h->type & NGX_HUNK_LAST_SHADOW) { | 374 if (h->type & NGX_HUNK_LAST_SHADOW) { |
545 #if 0 | |
546 h->shadow->last = h->shadow->pos; | |
547 #else | |
548 h->shadow->last = h->shadow->pos = h->shadow->start; | 375 h->shadow->last = h->shadow->pos = h->shadow->start; |
549 #endif | 376 } |
550 } | 377 |
551 | 378 ngx_chain_add_ce(p->out, p->last_out, ce); |
552 if (p->out_hunks) { | 379 } |
553 p->last_out_hunk->next = entry; | 380 |
554 | 381 p->in = in; |
555 } else { | 382 p->last_in = last; |
556 p->out_hunks = entry; | |
557 } | |
558 | |
559 p->last_out_hunk = entry; | |
560 } | |
561 | |
562 p->file_hunks = p->read_hunks; | |
563 | |
564 p->read_hunks = saved_read; | |
565 p->in_hunks = saved_in; | |
566 | 383 |
567 return NGX_OK; | 384 return NGX_OK; |
568 } | 385 } |
569 | 386 |
570 | 387 |
591 h->shadow = hunk; | 408 h->shadow = hunk; |
592 h->type |= NGX_HUNK_LAST_SHADOW|NGX_HUNK_RECYCLED; | 409 h->type |= NGX_HUNK_LAST_SHADOW|NGX_HUNK_RECYCLED; |
593 hunk->shadow = h; | 410 hunk->shadow = h; |
594 | 411 |
595 ngx_alloc_ce_and_set_hunk(ce, h, p->pool, NGX_ERROR); | 412 ngx_alloc_ce_and_set_hunk(ce, h, p->pool, NGX_ERROR); |
596 ngx_chain_add_ce(p->in_hunk, p->last_in_hunk, ce); | 413 ngx_chain_add_ce(p->in, p->last_in, ce); |
597 | 414 |
598 return NGX_OK; | 415 return NGX_OK; |
599 } | 416 } |
600 | 417 |
601 | 418 |
602 ngx_inline static void ngx_remove_shadow_links(ngx_chain_t *ce) | 419 ngx_inline static void ngx_remove_shadow_links(ngx_hunk_t *hunk) |
603 { | 420 { |
604 for ( | 421 ngx_hunk_t *h, *next; |
605 } | 422 |
606 | 423 if (hunk->shadow == NULL) { |
607 | 424 return; |
608 ngx_inline static void ngx_remove_shadow_free_raw_hunk(ngx_chain_t **free; | 425 } |
609 ngx_hunk_t *h); | 426 |
610 { | 427 h = hunk->shadow; |
611 ngx_hunk_t *s; | 428 |
429 while (!(h->type & NGX_HUNK_LAST_SHADOW)) { | |
430 next = h->shadow; | |
431 h->type &= ~(NGX_HUNK_TEMP|NGX_HUNK_IN_MEMORY|NGX_HUNK_RECYCLED); | |
432 h->shadow = NULL; | |
433 h = next; | |
434 } | |
435 | |
436 h->type &= ~(NGX_HUNK_TEMP | |
437 |NGX_HUNK_IN_MEMORY | |
438 |NGX_HUNK_RECYCLED | |
439 |NGX_HUNK_LAST_SHADOW); | |
440 h->shadow = NULL; | |
441 | |
442 hunk->shadow = NULL; | |
443 } | |
444 | |
445 | |
446 ngx_inline static void ngx_remove_shadow_free_raw_hunk(ngx_chain_t **free, | |
447 ngx_hunk_t *h) | |
448 { | |
449 ngx_hunk_t *s; | |
450 ngx_chain_t *ce, **le; | |
612 | 451 |
613 if (h->shadow == NULL) { | 452 if (h->shadow == NULL) { |
614 return; | 453 return; |
615 } | 454 } |
616 | 455 |
633 le = &ce->next; | 472 le = &ce->next; |
634 } | 473 } |
635 } | 474 } |
636 | 475 |
637 | 476 |
638 ngx_inline static void ngx_add_after_partially_filled_hunk(ngx_chain_t *chain, | 477 ngx_inline static void ngx_add_after_partially_filled_hunk(ngx_chain_t **chain, |
639 ngx_chain_t *ce) | 478 ngx_chain_t *ce) |
640 { | 479 { |
641 if (chain->hunk->pos != chain->hunk->last) { | 480 if (*chain == NULL) { |
642 ce->next = chain->next; | 481 *chain = ce; |
643 chain->next = ce; | 482 return; |
483 } | |
484 | |
485 if ((*chain)->hunk->pos != (*chain)->hunk->last) { | |
486 ce->next = (*chain)->next; | |
487 (*chain)->next = ce; | |
644 | 488 |
645 } else { | 489 } else { |
646 ce->next = chain; | 490 ce->next = (*chain); |
647 chain = ce; | 491 (*chain) = ce; |
648 } | 492 } |
649 } | 493 } |