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 }