Mercurial > hg > nginx
comparison src/http/ngx_http_request.c @ 5096:63014d919fec
Allocate request object from its own pool.
Previously, it was allocated from a connection pool and
was selectively freed for an idle keepalive connection.
The goal is to put coupled things in one chunk of memory,
and to simplify handling of request objects.
author | Valentin Bartenev <vbart@nginx.com> |
---|---|
date | Fri, 01 Mar 2013 14:55:42 +0000 |
parents | 4fbef397c753 |
children | d346adac0462 |
comparison
equal
deleted
inserted
replaced
5095:4fbef397c753 | 5096:63014d919fec |
---|---|
363 | 363 |
364 | 364 |
365 static void | 365 static void |
366 ngx_http_init_request(ngx_event_t *rev) | 366 ngx_http_init_request(ngx_event_t *rev) |
367 { | 367 { |
368 ngx_pool_t *pool; | |
368 ngx_time_t *tp; | 369 ngx_time_t *tp; |
369 ngx_connection_t *c; | 370 ngx_connection_t *c; |
370 ngx_http_request_t *r; | 371 ngx_http_request_t *r; |
371 ngx_http_log_ctx_t *ctx; | 372 ngx_http_log_ctx_t *ctx; |
372 ngx_http_connection_t *hc; | 373 ngx_http_connection_t *hc; |
385 | 386 |
386 c->requests++; | 387 c->requests++; |
387 | 388 |
388 hc = c->data; | 389 hc = c->data; |
389 | 390 |
390 r = hc->request; | 391 cscf = ngx_http_get_module_srv_conf(hc->conf_ctx, ngx_http_core_module); |
391 | 392 |
392 if (r) { | 393 pool = ngx_create_pool(cscf->request_pool_size, c->log); |
393 ngx_memzero(r, sizeof(ngx_http_request_t)); | 394 if (pool == NULL) { |
394 | 395 ngx_http_close_connection(c); |
395 r->pipeline = hc->pipeline; | 396 return; |
396 | 397 } |
397 if (hc->nbusy) { | 398 |
398 r->header_in = hc->busy[0]; | 399 r = ngx_pcalloc(pool, sizeof(ngx_http_request_t)); |
399 } | 400 if (r == NULL) { |
400 | 401 ngx_destroy_pool(pool); |
401 } else { | 402 ngx_http_close_connection(c); |
402 r = ngx_pcalloc(c->pool, sizeof(ngx_http_request_t)); | 403 return; |
403 if (r == NULL) { | 404 } |
404 ngx_http_close_connection(c); | 405 |
405 return; | 406 r->pool = pool; |
406 } | 407 |
407 | 408 r->pipeline = hc->pipeline; |
408 hc->request = r; | |
409 } | |
410 | 409 |
411 c->data = r; | 410 c->data = r; |
412 r->http_connection = hc; | 411 r->http_connection = hc; |
413 | 412 |
414 c->sent = 0; | 413 c->sent = 0; |
423 r->read_event_handler = ngx_http_block_reading; | 422 r->read_event_handler = ngx_http_block_reading; |
424 | 423 |
425 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); | 424 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); |
426 | 425 |
427 ngx_http_set_connection_log(r->connection, clcf->error_log); | 426 ngx_http_set_connection_log(r->connection, clcf->error_log); |
428 | |
429 cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module); | |
430 | 427 |
431 if (c->buffer == NULL) { | 428 if (c->buffer == NULL) { |
432 c->buffer = ngx_create_temp_buf(c->pool, | 429 c->buffer = ngx_create_temp_buf(c->pool, |
433 cscf->client_header_buffer_size); | 430 cscf->client_header_buffer_size); |
434 if (c->buffer == NULL) { | 431 if (c->buffer == NULL) { |
432 ngx_destroy_pool(r->pool); | |
435 ngx_http_close_connection(c); | 433 ngx_http_close_connection(c); |
436 return; | 434 return; |
437 } | 435 } |
438 } | 436 } |
439 | 437 |
440 if (r->header_in == NULL) { | 438 r->header_in = hc->nbusy ? hc->busy[0] : c->buffer; |
441 r->header_in = c->buffer; | |
442 } | |
443 | |
444 r->pool = ngx_create_pool(cscf->request_pool_size, c->log); | |
445 if (r->pool == NULL) { | |
446 ngx_http_close_connection(c); | |
447 return; | |
448 } | |
449 | |
450 | 439 |
451 if (ngx_list_init(&r->headers_out.headers, r->pool, 20, | 440 if (ngx_list_init(&r->headers_out.headers, r->pool, 20, |
452 sizeof(ngx_table_elt_t)) | 441 sizeof(ngx_table_elt_t)) |
453 != NGX_OK) | 442 != NGX_OK) |
454 { | 443 { |
2661 hc->busy[0] = b; | 2650 hc->busy[0] = b; |
2662 hc->nbusy = 1; | 2651 hc->nbusy = 1; |
2663 } | 2652 } |
2664 } | 2653 } |
2665 | 2654 |
2655 /* guard against recursive call from ngx_http_finalize_connection() */ | |
2666 r->keepalive = 0; | 2656 r->keepalive = 0; |
2667 | 2657 |
2668 ngx_http_free_request(r, 0); | 2658 ngx_http_free_request(r, 0); |
2669 | 2659 |
2670 c->data = hc; | 2660 c->data = hc; |
2692 } | 2682 } |
2693 | 2683 |
2694 hc->pipeline = 0; | 2684 hc->pipeline = 0; |
2695 | 2685 |
2696 /* | 2686 /* |
2697 * To keep a memory footprint as small as possible for an idle | 2687 * To keep a memory footprint as small as possible for an idle keepalive |
2698 * keepalive connection we try to free the ngx_http_request_t and | 2688 * connection we try to free c->buffer's memory if it was allocated outside |
2699 * c->buffer's memory if they were allocated outside the c->pool. | 2689 * the c->pool. The large header buffers are always allocated outside the |
2700 * The large header buffers are always allocated outside the c->pool and | 2690 * c->pool and are freed too. |
2701 * are freed too. | |
2702 */ | 2691 */ |
2703 | |
2704 if (ngx_pfree(c->pool, r) == NGX_OK) { | |
2705 hc->request = NULL; | |
2706 } | |
2707 | 2692 |
2708 b = c->buffer; | 2693 b = c->buffer; |
2709 | 2694 |
2710 if (ngx_pfree(c->pool, b->start) == NGX_OK) { | 2695 if (ngx_pfree(c->pool, b->start) == NGX_OK) { |
2711 | 2696 |
3153 | 3138 |
3154 static void | 3139 static void |
3155 ngx_http_free_request(ngx_http_request_t *r, ngx_int_t rc) | 3140 ngx_http_free_request(ngx_http_request_t *r, ngx_int_t rc) |
3156 { | 3141 { |
3157 ngx_log_t *log; | 3142 ngx_log_t *log; |
3143 ngx_pool_t *pool; | |
3158 struct linger linger; | 3144 struct linger linger; |
3159 ngx_http_cleanup_t *cln; | 3145 ngx_http_cleanup_t *cln; |
3160 ngx_http_log_ctx_t *ctx; | 3146 ngx_http_log_ctx_t *ctx; |
3161 ngx_http_core_loc_conf_t *clcf; | 3147 ngx_http_core_loc_conf_t *clcf; |
3162 | 3148 |
3219 | 3205 |
3220 r->request_line.len = 0; | 3206 r->request_line.len = 0; |
3221 | 3207 |
3222 r->connection->destroyed = 1; | 3208 r->connection->destroyed = 1; |
3223 | 3209 |
3224 ngx_destroy_pool(r->pool); | 3210 /* |
3211 * Setting r->pool to NULL will increase probability to catch double close | |
3212 * of request since the request object is allocated from its own pool. | |
3213 */ | |
3214 | |
3215 pool = r->pool; | |
3216 r->pool = NULL; | |
3217 | |
3218 ngx_destroy_pool(pool); | |
3225 } | 3219 } |
3226 | 3220 |
3227 | 3221 |
3228 static void | 3222 static void |
3229 ngx_http_log_request(ngx_http_request_t *r) | 3223 ngx_http_log_request(ngx_http_request_t *r) |