# HG changeset patch # User Valentin Bartenev # Date 1362149742 0 # Node ID 63014d919fec96886fedb5e7c330e1ffdc5a84cc # Parent 4fbef397c7538094eb6d6f13556fd32699aa776d 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. diff -r 4fbef397c753 -r 63014d919fec src/http/ngx_http_request.c --- a/src/http/ngx_http_request.c Wed Feb 27 17:41:34 2013 +0000 +++ b/src/http/ngx_http_request.c Fri Mar 01 14:55:42 2013 +0000 @@ -365,6 +365,7 @@ static void ngx_http_init_request(ngx_event_t *rev) { + ngx_pool_t *pool; ngx_time_t *tp; ngx_connection_t *c; ngx_http_request_t *r; @@ -387,27 +388,25 @@ hc = c->data; - r = hc->request; - - if (r) { - ngx_memzero(r, sizeof(ngx_http_request_t)); - - r->pipeline = hc->pipeline; - - if (hc->nbusy) { - r->header_in = hc->busy[0]; - } - - } else { - r = ngx_pcalloc(c->pool, sizeof(ngx_http_request_t)); - if (r == NULL) { - ngx_http_close_connection(c); - return; - } - - hc->request = r; + cscf = ngx_http_get_module_srv_conf(hc->conf_ctx, ngx_http_core_module); + + pool = ngx_create_pool(cscf->request_pool_size, c->log); + if (pool == NULL) { + ngx_http_close_connection(c); + return; } + r = ngx_pcalloc(pool, sizeof(ngx_http_request_t)); + if (r == NULL) { + ngx_destroy_pool(pool); + ngx_http_close_connection(c); + return; + } + + r->pool = pool; + + r->pipeline = hc->pipeline; + c->data = r; r->http_connection = hc; @@ -426,27 +425,17 @@ ngx_http_set_connection_log(r->connection, clcf->error_log); - cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module); - if (c->buffer == NULL) { c->buffer = ngx_create_temp_buf(c->pool, cscf->client_header_buffer_size); if (c->buffer == NULL) { + ngx_destroy_pool(r->pool); ngx_http_close_connection(c); return; } } - if (r->header_in == NULL) { - r->header_in = c->buffer; - } - - r->pool = ngx_create_pool(cscf->request_pool_size, c->log); - if (r->pool == NULL) { - ngx_http_close_connection(c); - return; - } - + r->header_in = hc->nbusy ? hc->busy[0] : c->buffer; if (ngx_list_init(&r->headers_out.headers, r->pool, 20, sizeof(ngx_table_elt_t)) @@ -2663,6 +2652,7 @@ } } + /* guard against recursive call from ngx_http_finalize_connection() */ r->keepalive = 0; ngx_http_free_request(r, 0); @@ -2694,17 +2684,12 @@ hc->pipeline = 0; /* - * To keep a memory footprint as small as possible for an idle - * keepalive connection we try to free the ngx_http_request_t and - * c->buffer's memory if they were allocated outside the c->pool. - * The large header buffers are always allocated outside the c->pool and - * are freed too. + * To keep a memory footprint as small as possible for an idle keepalive + * connection we try to free c->buffer's memory if it was allocated outside + * the c->pool. The large header buffers are always allocated outside the + * c->pool and are freed too. */ - if (ngx_pfree(c->pool, r) == NGX_OK) { - hc->request = NULL; - } - b = c->buffer; if (ngx_pfree(c->pool, b->start) == NGX_OK) { @@ -3155,6 +3140,7 @@ ngx_http_free_request(ngx_http_request_t *r, ngx_int_t rc) { ngx_log_t *log; + ngx_pool_t *pool; struct linger linger; ngx_http_cleanup_t *cln; ngx_http_log_ctx_t *ctx; @@ -3221,7 +3207,15 @@ r->connection->destroyed = 1; - ngx_destroy_pool(r->pool); + /* + * Setting r->pool to NULL will increase probability to catch double close + * of request since the request object is allocated from its own pool. + */ + + pool = r->pool; + r->pool = NULL; + + ngx_destroy_pool(pool); } diff -r 4fbef397c753 -r 63014d919fec src/http/ngx_http_request.h --- a/src/http/ngx_http_request.h Wed Feb 27 17:41:34 2013 +0000 +++ b/src/http/ngx_http_request.h Fri Mar 01 14:55:42 2013 +0000 @@ -302,8 +302,6 @@ #endif #endif - ngx_http_request_t *request; - ngx_buf_t **busy; ngx_int_t nbusy;