Mercurial > hg > nginx
comparison src/event/ngx_event_proxy.c @ 152:fb48bf4fea1c
nginx-0.0.1-2003-10-21-11:47:21 import
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Tue, 21 Oct 2003 07:47:21 +0000 |
parents | 2d9e4a8b6d11 |
children |
comparison
equal
deleted
inserted
replaced
151:2d9e4a8b6d11 | 152:fb48bf4fea1c |
---|---|
8 ngx_inline static void ngx_remove_shadow_links(ngx_hunk_t *hunk); | 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, | 9 ngx_inline static void ngx_remove_shadow_free_raw_hunk(ngx_chain_t **free, |
10 ngx_hunk_t *h); | 10 ngx_hunk_t *h); |
11 ngx_inline static void ngx_add_after_partially_filled_hunk(ngx_chain_t **chain, | 11 ngx_inline static void ngx_add_after_partially_filled_hunk(ngx_chain_t **chain, |
12 ngx_chain_t *ce); | 12 ngx_chain_t *ce); |
13 static int ngx_drain_chains(ngx_event_proxy_t *p); | |
13 | 14 |
14 | 15 |
15 int ngx_event_proxy(ngx_event_proxy_t *p, int do_write) | 16 int ngx_event_proxy(ngx_event_proxy_t *p, int do_write) |
16 { | 17 { |
17 for ( ;; ) { | 18 for ( ;; ) { |
51 { | 52 { |
52 int n, rc, size; | 53 int n, rc, size; |
53 ngx_hunk_t *h; | 54 ngx_hunk_t *h; |
54 ngx_chain_t *chain, *ce, *te; | 55 ngx_chain_t *chain, *ce, *te; |
55 | 56 |
57 if (p->upstream_eof || p->upstream_error || p->upstream_done) { | |
58 return NGX_OK; | |
59 } | |
60 | |
56 ngx_log_debug(p->log, "read upstream: %d" _ p->upstream->read->ready); | 61 ngx_log_debug(p->log, "read upstream: %d" _ p->upstream->read->ready); |
57 | 62 |
58 while (p->preread_hunks | 63 for ( ;; ) { |
59 || (p->upstream->read->ready && !p->upstream_done)) | 64 |
60 { | 65 if (p->upstream_eof || p->upstream_error || p->upstream_done) { |
66 break; | |
67 } | |
68 | |
69 if (p->preread_hunks == NULL && !p->upstream->read->ready) { | |
70 break; | |
71 } | |
72 | |
61 if (p->preread_hunks) { | 73 if (p->preread_hunks) { |
62 | 74 |
63 /* use the pre-read hunks if they exist */ | 75 /* use the pre-read hunks if they exist */ |
64 | 76 |
65 p->read = 1; | 77 p->read = 1; |
182 | 194 |
183 if (n == NGX_AGAIN) { | 195 if (n == NGX_AGAIN) { |
184 break; | 196 break; |
185 } | 197 } |
186 | 198 |
187 /* TODO THINK about eof */ | |
188 p->read = 1; | 199 p->read = 1; |
189 | 200 |
190 if (n == 0) { | 201 if (n == 0) { |
191 p->upstream_eof = 1; | 202 p->upstream_eof = 1; |
192 break; | 203 break; |
193 } | 204 } |
194 | |
195 } | 205 } |
196 | 206 |
197 ce = chain; | 207 ce = chain; |
198 | 208 |
199 while (ce && n > 0) { | 209 while (ce && n > 0) { |
242 } | 252 } |
243 | 253 |
244 | 254 |
245 int ngx_event_proxy_write_to_downstream(ngx_event_proxy_t *p) | 255 int ngx_event_proxy_write_to_downstream(ngx_event_proxy_t *p) |
246 { | 256 { |
247 int rc; | 257 size_t busy_len; |
248 ngx_hunk_t *h; | 258 ngx_hunk_t *h; |
249 ngx_chain_t *out, *ce, *te; | 259 ngx_chain_t *out, *ce, *te; |
250 | 260 |
251 ngx_log_debug(p->log, "write downstream: %d" _ p->downstream->write->ready); | 261 ngx_log_debug(p->log, "write downstream: %d" _ p->downstream->write->ready); |
252 | 262 |
253 for ( ;; ) { | 263 for ( ;; ) { |
264 if (p->downstream_error) { | |
265 return ngx_drain_chains(p); | |
266 } | |
254 | 267 |
255 if ((p->upstream_eof || p->upstream_error || p->upstream_done) | 268 if ((p->upstream_eof || p->upstream_error || p->upstream_done) |
256 && p->out == NULL && p->in == NULL) | 269 && p->out == NULL && p->in == NULL) |
257 { | 270 { |
258 p->downstream_done = 1; | 271 p->downstream_done = 1; |
261 | 274 |
262 if (!p->downstream->write->ready) { | 275 if (!p->downstream->write->ready) { |
263 break; | 276 break; |
264 } | 277 } |
265 | 278 |
279 busy_len = 0; | |
280 | |
281 if (!(p->upstream_eof || p->upstream_error || p->upstream_done)) { | |
282 /* calculate p->busy_len */ | |
283 for (ce = p->busy; ce; ce = ce->next) { | |
284 busy_len += ngx_hunk_size(ce->hunk); | |
285 } | |
286 } | |
287 | |
288 | |
266 if (p->out) { | 289 if (p->out) { |
267 out = p->out; | 290 out = p->out; |
268 | 291 |
269 if (p->busy_len + ngx_hunk_size(out->hunk) > p->max_busy_len) { | 292 if (!(p->upstream_eof || p->upstream_error || p->upstream_done) |
293 && (busy_len + ngx_hunk_size(out->hunk) > p->max_busy_len)) | |
294 { | |
270 break; | 295 break; |
271 } | 296 } |
272 | 297 |
273 p->out = p->out->next; | 298 p->out = p->out->next; |
274 ngx_remove_shadow_free_raw_hunk(&p->free_raw_hunks, out->hunk); | 299 ngx_remove_shadow_free_raw_hunk(&p->free_raw_hunks, out->hunk); |
275 | 300 |
276 } else if (!p->cachable && p->in) { | 301 } else if (!p->cachable && p->in) { |
277 out = p->in; | 302 out = p->in; |
278 | 303 |
279 if (!(p->upstream_eof || p->upstream_error || p->upstream_done) | 304 if (!(p->upstream_eof || p->upstream_error || p->upstream_done) |
280 && (p->busy_len + ngx_hunk_size(out->hunk) > p->max_busy_len)) | 305 && (busy_len + ngx_hunk_size(out->hunk) > p->max_busy_len)) |
281 { | 306 { |
282 break; | 307 break; |
283 } | 308 } |
284 | 309 |
285 p->in = p->in->next; | 310 p->in = p->in->next; |
288 break; | 313 break; |
289 } | 314 } |
290 | 315 |
291 out->next = NULL; | 316 out->next = NULL; |
292 | 317 |
293 rc = p->output_filter(p->output_ctx, out->hunk); | 318 |
294 | 319 if (p->output_filter(p->output_ctx, out->hunk) == NGX_ERROR) { |
295 if (rc == NGX_ERROR) { | |
296 p->downstream_error = 1; | 320 p->downstream_error = 1; |
297 return NGX_ERROR; | 321 continue; |
298 } | 322 } |
299 | 323 |
300 ngx_chain_update_chains(&p->free, &p->busy, &out); | 324 ngx_chain_update_chains(&p->free, &p->busy, &out); |
301 | |
302 /* calculate p->busy_len */ | |
303 | |
304 p->busy_len = 0; | |
305 for (ce = p->busy; ce; ce = ce->next) { | |
306 p->busy_len += ngx_hunk_size(ce->hunk); | |
307 } | |
308 | 325 |
309 /* add the free shadow raw hunks to p->free_raw_hunks */ | 326 /* add the free shadow raw hunks to p->free_raw_hunks */ |
310 | 327 |
311 for (ce = p->free; ce; ce = ce->next) { | 328 for (ce = p->free; ce; ce = ce->next) { |
312 ngx_log_debug(p->log, "SHADOW %08X" _ ce->hunk->shadow); | 329 ngx_log_debug(p->log, "SHADOW %08X" _ ce->hunk->shadow); |
321 | 338 |
322 ce->hunk->type &= ~NGX_HUNK_LAST_SHADOW; | 339 ce->hunk->type &= ~NGX_HUNK_LAST_SHADOW; |
323 } | 340 } |
324 ce->hunk->shadow = NULL; | 341 ce->hunk->shadow = NULL; |
325 } | 342 } |
326 | |
327 #if 0 /* TODO THINK p->read_priority ??? */ | |
328 if (p->upstream->read->ready) { | |
329 return; | |
330 } | |
331 #endif | |
332 | |
333 } | 343 } |
334 | 344 |
335 ngx_log_debug(p->log, "STATE %d:%d:%d:%X:%X" _ | 345 ngx_log_debug(p->log, "STATE %d:%d:%d:%X:%X" _ |
336 p->upstream_eof _ | 346 p->upstream_eof _ |
337 p->upstream_error _ | 347 p->upstream_error _ |
338 p->upstream_done _ | 348 p->upstream_done _ |
339 p->in _ | 349 p->in _ |
340 p->out | 350 p->out |
341 ); | 351 ); |
342 | 352 |
343 if ((p->upstream_eof || p->upstream_error || p->upstream_done) | |
344 && p->in == NULL && p->out == NULL) | |
345 { | |
346 p->downstream_done = 1; | |
347 } | |
348 | |
349 return NGX_OK; | 353 return NGX_OK; |
350 } | 354 } |
351 | 355 |
352 | 356 |
353 static int ngx_event_proxy_write_chain_to_temp_file(ngx_event_proxy_t *p) | 357 static int ngx_event_proxy_write_chain_to_temp_file(ngx_event_proxy_t *p) |
354 { | 358 { |
355 int rc, size; | 359 int rc, size, hunk_size; |
356 ngx_hunk_t *h; | 360 ngx_hunk_t *h; |
357 ngx_chain_t *ce, *te, *next, *in, **last, **last_free; | 361 ngx_chain_t *ce, *te, *next, *in, **le, **last_free; |
358 | 362 |
359 ngx_log_debug(p->log, "write to file"); | 363 ngx_log_debug(p->log, "write to file"); |
360 | 364 |
361 if (p->temp_file->fd == NGX_INVALID_FILE) { | 365 if (p->temp_file->fd == NGX_INVALID_FILE) { |
362 rc = ngx_create_temp_file(p->temp_file, p->temp_path, p->pool, | 366 rc = ngx_create_temp_file(p->temp_file, p->temp_path, p->pool, |
377 | 381 |
378 if (!p->cachable) { | 382 if (!p->cachable) { |
379 | 383 |
380 size = 0; | 384 size = 0; |
381 ce = p->in; | 385 ce = p->in; |
386 le = NULL; | |
387 | |
388 ngx_log_debug(p->log, "offset: %d" _ p->temp_offset); | |
382 | 389 |
383 do { | 390 do { |
384 if (size + ce->hunk->last - ce->hunk->pos | 391 hunk_size = ce->hunk->last - ce->hunk->pos; |
385 >= p->temp_file_write_size) | 392 |
393 ngx_log_debug(p->log, "hunk size: %d" _ hunk_size); | |
394 | |
395 if ((size + hunk_size > p->temp_file_write_size) | |
396 || (p->temp_offset + hunk_size > p->max_temp_file_size)) | |
386 { | 397 { |
387 break; | 398 break; |
388 } | 399 } |
389 size += ce->hunk->last - ce->hunk->pos; | 400 |
401 size += hunk_size; | |
402 le = &ce->next; | |
390 ce = ce->next; | 403 ce = ce->next; |
391 | 404 |
392 } while (ce); | 405 } while (ce); |
393 | 406 |
407 ngx_log_debug(p->log, "size: %d" _ size); | |
408 | |
394 if (ce) { | 409 if (ce) { |
395 in = ce->next; | 410 in = ce; |
396 last = &ce->next; | 411 *le = NULL; |
397 ce->next = NULL; | |
398 | 412 |
399 } else { | 413 } else { |
400 in = NULL; | 414 in = NULL; |
401 last = &p->in; | 415 p->last_in = &p->in; |
402 } | 416 } |
403 | 417 |
404 } else { | 418 } else { |
405 in = NULL; | 419 in = NULL; |
406 last = &p->in; | 420 p->last_in = &p->in; |
407 } | 421 } |
408 | 422 |
409 if (ngx_write_chain_to_file(p->temp_file, p->in, p->temp_offset, | 423 if (ngx_write_chain_to_file(p->temp_file, p->in, p->temp_offset, |
410 p->pool) == NGX_ERROR) { | 424 p->pool) == NGX_ERROR) { |
411 return NGX_ABORT; | 425 return NGX_ABORT; |
412 } | 426 } |
413 | 427 |
414 for (last_free = &p->free_raw_hunks; | 428 for (last_free = &p->free_raw_hunks; |
415 *last_free != NULL; | 429 *last_free != NULL; |
416 last_free = &(*last)->next) | 430 last_free = &(*last_free)->next) |
417 { | 431 { |
418 /* void */ | 432 /* void */ |
419 } | 433 } |
420 | 434 |
421 for (ce = p->in; ce; ce = next) { | 435 for (ce = p->in; ce; ce = next) { |
438 last_free = &te->next; | 452 last_free = &te->next; |
439 } | 453 } |
440 } | 454 } |
441 | 455 |
442 p->in = in; | 456 p->in = in; |
443 p->last_in = last; | |
444 | 457 |
445 return NGX_OK; | 458 return NGX_OK; |
446 } | 459 } |
447 | 460 |
448 | 461 |
550 } else { | 563 } else { |
551 ce->next = (*chain); | 564 ce->next = (*chain); |
552 (*chain) = ce; | 565 (*chain) = ce; |
553 } | 566 } |
554 } | 567 } |
568 | |
569 | |
570 static int ngx_drain_chains(ngx_event_proxy_t *p) | |
571 { | |
572 ngx_hunk_t *h; | |
573 ngx_chain_t *ce, *te; | |
574 | |
575 for ( ;; ) { | |
576 if (p->busy) { | |
577 ce = p->busy; | |
578 | |
579 } else if (p->out) { | |
580 ce = p->out; | |
581 | |
582 } else if (p->in) { | |
583 ce = p->in; | |
584 | |
585 } else { | |
586 return NGX_OK; | |
587 } | |
588 | |
589 while (ce) { | |
590 if (ce->hunk->type & NGX_HUNK_LAST_SHADOW) { | |
591 h = ce->hunk->shadow; | |
592 /* THINK NEEDED ??? */ h->pos = h->last = h->start; | |
593 h->shadow = NULL; | |
594 ngx_alloc_ce_and_set_hunk(te, h, p->pool, NGX_ABORT); | |
595 ngx_add_after_partially_filled_hunk(&p->free_raw_hunks, te); | |
596 | |
597 ce->hunk->type &= ~NGX_HUNK_LAST_SHADOW; | |
598 } | |
599 | |
600 ce->hunk->shadow = NULL; | |
601 te = ce->next; | |
602 ce->next = p->free; | |
603 p->free = ce; | |
604 ce = te; | |
605 } | |
606 } | |
607 } |