Mercurial > hg > nginx
changeset 3049:67254117b774
request reference counter
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Wed, 26 Aug 2009 16:04:05 +0000 |
parents | 846d0e2fa483 |
children | f54b02dbb12b |
files | src/http/ngx_http_core_module.c src/http/ngx_http_request.c src/http/ngx_http_request.h src/http/ngx_http_request_body.c |
diffstat | 4 files changed, 109 insertions(+), 27 deletions(-) [+] |
line wrap: on
line diff
--- a/src/http/ngx_http_core_module.c +++ b/src/http/ngx_http_core_module.c @@ -1260,10 +1260,6 @@ ngx_http_core_content_phase(ngx_http_req rc = ph->handler(r); - if (rc == NGX_DONE) { - return NGX_OK; - } - if (rc != NGX_DECLINED) { ngx_http_finalize_request(r, rc); return NGX_OK; @@ -2126,6 +2122,7 @@ ngx_http_subrequest(ngx_http_request_t * sr->uri_changes = NGX_HTTP_MAX_URI_CHANGES + 1; r->main->subrequests++; + r->main->count++; *psr = sr; @@ -2178,6 +2175,7 @@ ngx_http_internal_redirect(ngx_http_requ #endif r->internal = 1; + r->main->count++; ngx_http_handler(r); @@ -2192,6 +2190,8 @@ ngx_http_named_location(ngx_http_request ngx_http_core_loc_conf_t **clcfp; ngx_http_core_main_conf_t *cmcf; + r->main->count++; + cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module); if (cscf->named_locations) {
--- a/src/http/ngx_http_request.c +++ b/src/http/ngx_http_request.c @@ -36,6 +36,9 @@ static ngx_int_t ngx_http_find_virtual_s u_char *host, size_t len); static void ngx_http_request_handler(ngx_event_t *ev); +static void ngx_http_terminate_request(ngx_http_request_t *r, ngx_int_t rc); +static void ngx_http_terminate_handler(ngx_http_request_t *r); +static void ngx_http_finalize_connection(ngx_http_request_t *r); static ngx_int_t ngx_http_set_write_handler(ngx_http_request_t *r); static void ngx_http_writer(ngx_http_request_t *r); static void ngx_http_request_finalizer(ngx_http_request_t *r); @@ -46,7 +49,7 @@ static void ngx_http_set_lingering_close static void ngx_http_lingering_close_handler(ngx_event_t *ev); static ngx_int_t ngx_http_post_action(ngx_http_request_t *r); static void ngx_http_close_request(ngx_http_request_t *r, ngx_int_t error); -static void ngx_http_request_done(ngx_http_request_t *r, ngx_int_t error); +static void ngx_http_free_request(ngx_http_request_t *r, ngx_int_t error); static void ngx_http_log_request(ngx_http_request_t *r); static void ngx_http_close_connection(ngx_connection_t *c); @@ -478,6 +481,7 @@ ngx_http_init_request(ngx_event_t *rev) c->destroyed = 0; r->main = r; + r->count = 1; tp = ngx_timeofday(); r->start_sec = tp->sec; @@ -1828,17 +1832,17 @@ ngx_http_finalize_request(ngx_http_reque ngx_http_request_t *pr; ngx_http_core_loc_conf_t *clcf; + c = r->connection; + + ngx_log_debug5(NGX_LOG_DEBUG_HTTP, c->log, 0, + "http finalize request: %d, \"%V?%V\" a:%d, c:%d", + rc, &r->uri, &r->args, r == c->data, r->main->count); + if (rc == NGX_DONE) { - /* the request pool may be already destroyed */ + ngx_http_finalize_connection(r); return; } - c = r->connection; - - ngx_log_debug4(NGX_LOG_DEBUG_HTTP, c->log, 0, - "http finalize request: %d, \"%V?%V\" %d", - rc, &r->uri, &r->args, r == c->data); - if (rc == NGX_OK && r->filter_finalize) { c->error = 1; return; @@ -1860,15 +1864,11 @@ ngx_http_finalize_request(ngx_http_reque || rc == NGX_HTTP_CLIENT_CLOSED_REQUEST || c->error) { - if (rc > 0 && r->headers_out.status == 0) { - r->headers_out.status = rc; - } - if (ngx_http_post_action(r) == NGX_OK) { return; } - ngx_http_close_request(r, 0); + ngx_http_terminate_request(r, rc); return; } @@ -1877,7 +1877,7 @@ ngx_http_finalize_request(ngx_http_reque || rc == NGX_HTTP_NO_CONTENT) { if (rc == NGX_HTTP_CLOSE) { - ngx_http_close_request(r, rc); + ngx_http_terminate_request(r, rc); return; } @@ -1903,7 +1903,7 @@ ngx_http_finalize_request(ngx_http_reque if (r->buffered || r->postponed) { if (ngx_http_set_write_handler(r) != NGX_OK) { - ngx_http_close_request(r->main, 0); + ngx_http_terminate_request(r, 0); } return; @@ -1921,6 +1921,8 @@ ngx_http_finalize_request(ngx_http_reque if (r == c->data) { + r->main->count--; + if (!r->logged) { clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); @@ -1955,7 +1957,8 @@ ngx_http_finalize_request(ngx_http_reque } if (ngx_http_post_request(pr) != NGX_OK) { - ngx_http_close_request(r->main, 0); + r->main->count++; + ngx_http_terminate_request(r, 0); return; } @@ -1969,7 +1972,7 @@ ngx_http_finalize_request(ngx_http_reque if (r->buffered || c->buffered || r->postponed) { if (ngx_http_set_write_handler(r) != NGX_OK) { - ngx_http_close_request(r, 0); + ngx_http_terminate_request(r, 0); } return; @@ -2010,6 +2013,68 @@ ngx_http_finalize_request(ngx_http_reque return; } + ngx_http_finalize_connection(r); +} + + +static void +ngx_http_terminate_request(ngx_http_request_t *r, ngx_int_t rc) +{ + ngx_http_cleanup_t *cln; + ngx_http_request_t *mr; + + mr = r->main; + + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + "http terminate request count: %d", mr->count); + + cln = mr->cleanup; + mr->cleanup = NULL; + + while (cln) { + if (cln->handler) { + cln->handler(cln->data); + } + + cln = cln->next; + } + + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + "http terminate cleanup count: %d", mr->count); + + if (mr->write_event_handler) { + mr->posted_requests = NULL; + mr->write_event_handler = ngx_http_terminate_handler; + (void) ngx_http_post_request(mr); + return; + } + + ngx_http_close_request(mr, rc); +} + + +static void +ngx_http_terminate_handler(ngx_http_request_t *r) +{ + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + "http terminate handler count: %d", r->count); + + r->count = 1; + + ngx_http_close_request(r, 0); +} + + +static void +ngx_http_finalize_connection(ngx_http_request_t *r) +{ + ngx_http_core_loc_conf_t *clcf; + + if (r->main->count != 1) { + ngx_http_close_request(r, 0); + return; + } + clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); if (!ngx_terminate @@ -2319,7 +2384,7 @@ ngx_http_set_keepalive(ngx_http_request_ } } - ngx_http_request_done(r, 0); + ngx_http_free_request(r, 0); c->data = hc; @@ -2766,19 +2831,33 @@ ngx_http_post_action(ngx_http_request_t static void -ngx_http_close_request(ngx_http_request_t *r, ngx_int_t error) +ngx_http_close_request(ngx_http_request_t *r, ngx_int_t rc) { ngx_connection_t *c; + r = r->main; c = r->connection; - ngx_http_request_done(r->main, error); + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, + "http request count: %d", r->count); + + if (r->count == 0) { + ngx_log_error(NGX_LOG_ALERT, c->log, 0, "http request count is zero"); + } + + r->count--; + + if (r->count) { + return; + } + + ngx_http_free_request(r, rc); ngx_http_close_connection(c); } static void -ngx_http_request_done(ngx_http_request_t *r, ngx_int_t error) +ngx_http_free_request(ngx_http_request_t *r, ngx_int_t rc) { ngx_log_t *log; struct linger linger; @@ -2813,8 +2892,8 @@ ngx_http_request_done(ngx_http_request_t #endif - if (error && r->headers_out.status == 0) { - r->headers_out.status = error; + if (rc > 0 && (r->headers_out.status == 0 || r->connection->sent == 0)) { + r->headers_out.status = rc; } log->action = "logging request";