request reference counter

This commit is contained in:
Igor Sysoev 2009-08-26 16:04:05 +00:00
parent 450659e62a
commit b603dd4b43
4 changed files with 110 additions and 28 deletions

View File

@ -1260,10 +1260,6 @@ ngx_http_core_content_phase(ngx_http_request_t *r,
rc = ph->handler(r); rc = ph->handler(r);
if (rc == NGX_DONE) {
return NGX_OK;
}
if (rc != NGX_DECLINED) { if (rc != NGX_DECLINED) {
ngx_http_finalize_request(r, rc); ngx_http_finalize_request(r, rc);
return NGX_OK; return NGX_OK;
@ -2126,6 +2122,7 @@ ngx_http_subrequest(ngx_http_request_t *r,
sr->uri_changes = NGX_HTTP_MAX_URI_CHANGES + 1; sr->uri_changes = NGX_HTTP_MAX_URI_CHANGES + 1;
r->main->subrequests++; r->main->subrequests++;
r->main->count++;
*psr = sr; *psr = sr;
@ -2178,6 +2175,7 @@ ngx_http_internal_redirect(ngx_http_request_t *r,
#endif #endif
r->internal = 1; r->internal = 1;
r->main->count++;
ngx_http_handler(r); ngx_http_handler(r);
@ -2192,6 +2190,8 @@ ngx_http_named_location(ngx_http_request_t *r, ngx_str_t *name)
ngx_http_core_loc_conf_t **clcfp; ngx_http_core_loc_conf_t **clcfp;
ngx_http_core_main_conf_t *cmcf; ngx_http_core_main_conf_t *cmcf;
r->main->count++;
cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module); cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
if (cscf->named_locations) { if (cscf->named_locations) {

View File

@ -36,6 +36,9 @@ static ngx_int_t ngx_http_find_virtual_server(ngx_http_request_t *r,
u_char *host, size_t len); u_char *host, size_t len);
static void ngx_http_request_handler(ngx_event_t *ev); 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 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_writer(ngx_http_request_t *r);
static void ngx_http_request_finalizer(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(ngx_http_request_t *r);
static void ngx_http_lingering_close_handler(ngx_event_t *ev); 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 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_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_log_request(ngx_http_request_t *r);
static void ngx_http_close_connection(ngx_connection_t *c); 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; c->destroyed = 0;
r->main = r; r->main = r;
r->count = 1;
tp = ngx_timeofday(); tp = ngx_timeofday();
r->start_sec = tp->sec; r->start_sec = tp->sec;
@ -1828,16 +1832,16 @@ ngx_http_finalize_request(ngx_http_request_t *r, ngx_int_t rc)
ngx_http_request_t *pr; ngx_http_request_t *pr;
ngx_http_core_loc_conf_t *clcf; ngx_http_core_loc_conf_t *clcf;
if (rc == NGX_DONE) {
/* the request pool may be already destroyed */
return;
}
c = r->connection; c = r->connection;
ngx_log_debug4(NGX_LOG_DEBUG_HTTP, c->log, 0, ngx_log_debug5(NGX_LOG_DEBUG_HTTP, c->log, 0,
"http finalize request: %d, \"%V?%V\" %d", "http finalize request: %d, \"%V?%V\" a:%d, c:%d",
rc, &r->uri, &r->args, r == c->data); rc, &r->uri, &r->args, r == c->data, r->main->count);
if (rc == NGX_DONE) {
ngx_http_finalize_connection(r);
return;
}
if (rc == NGX_OK && r->filter_finalize) { if (rc == NGX_OK && r->filter_finalize) {
c->error = 1; c->error = 1;
@ -1860,15 +1864,11 @@ ngx_http_finalize_request(ngx_http_request_t *r, ngx_int_t rc)
|| rc == NGX_HTTP_CLIENT_CLOSED_REQUEST || rc == NGX_HTTP_CLIENT_CLOSED_REQUEST
|| c->error) || c->error)
{ {
if (rc > 0 && r->headers_out.status == 0) {
r->headers_out.status = rc;
}
if (ngx_http_post_action(r) == NGX_OK) { if (ngx_http_post_action(r) == NGX_OK) {
return; return;
} }
ngx_http_close_request(r, 0); ngx_http_terminate_request(r, rc);
return; return;
} }
@ -1877,7 +1877,7 @@ ngx_http_finalize_request(ngx_http_request_t *r, ngx_int_t rc)
|| rc == NGX_HTTP_NO_CONTENT) || rc == NGX_HTTP_NO_CONTENT)
{ {
if (rc == NGX_HTTP_CLOSE) { if (rc == NGX_HTTP_CLOSE) {
ngx_http_close_request(r, rc); ngx_http_terminate_request(r, rc);
return; return;
} }
@ -1903,7 +1903,7 @@ ngx_http_finalize_request(ngx_http_request_t *r, ngx_int_t rc)
if (r->buffered || r->postponed) { if (r->buffered || r->postponed) {
if (ngx_http_set_write_handler(r) != NGX_OK) { if (ngx_http_set_write_handler(r) != NGX_OK) {
ngx_http_close_request(r->main, 0); ngx_http_terminate_request(r, 0);
} }
return; return;
@ -1921,6 +1921,8 @@ ngx_http_finalize_request(ngx_http_request_t *r, ngx_int_t rc)
if (r == c->data) { if (r == c->data) {
r->main->count--;
if (!r->logged) { if (!r->logged) {
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
@ -1955,7 +1957,8 @@ ngx_http_finalize_request(ngx_http_request_t *r, ngx_int_t rc)
} }
if (ngx_http_post_request(pr) != NGX_OK) { 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; return;
} }
@ -1969,7 +1972,7 @@ ngx_http_finalize_request(ngx_http_request_t *r, ngx_int_t rc)
if (r->buffered || c->buffered || r->postponed) { if (r->buffered || c->buffered || r->postponed) {
if (ngx_http_set_write_handler(r) != NGX_OK) { if (ngx_http_set_write_handler(r) != NGX_OK) {
ngx_http_close_request(r, 0); ngx_http_terminate_request(r, 0);
} }
return; return;
@ -2010,6 +2013,68 @@ ngx_http_finalize_request(ngx_http_request_t *r, ngx_int_t rc)
return; 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); clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
if (!ngx_terminate if (!ngx_terminate
@ -2319,7 +2384,7 @@ ngx_http_set_keepalive(ngx_http_request_t *r)
} }
} }
ngx_http_request_done(r, 0); ngx_http_free_request(r, 0);
c->data = hc; c->data = hc;
@ -2766,19 +2831,33 @@ ngx_http_post_action(ngx_http_request_t *r)
static void 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; ngx_connection_t *c;
r = r->main;
c = r->connection; 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); ngx_http_close_connection(c);
} }
static void 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; ngx_log_t *log;
struct linger linger; struct linger linger;
@ -2813,8 +2892,8 @@ ngx_http_request_done(ngx_http_request_t *r, ngx_int_t error)
#endif #endif
if (error && r->headers_out.status == 0) { if (rc > 0 && (r->headers_out.status == 0 || r->connection->sent == 0)) {
r->headers_out.status = error; r->headers_out.status = rc;
} }
log->action = "logging request"; log->action = "logging request";

View File

@ -502,6 +502,7 @@ struct ngx_http_request_s {
#endif #endif
unsigned subrequests:8; unsigned subrequests:8;
unsigned count:8;
/* used to parse HTTP headers */ /* used to parse HTTP headers */

View File

@ -37,6 +37,8 @@ ngx_http_read_client_request_body(ngx_http_request_t *r,
ngx_http_request_body_t *rb; ngx_http_request_body_t *rb;
ngx_http_core_loc_conf_t *clcf; ngx_http_core_loc_conf_t *clcf;
r->main->count++;
if (r->request_body || r->discard_body) { if (r->request_body || r->discard_body) {
post_handler(r); post_handler(r);
return NGX_OK; return NGX_OK;