Mercurial > hg > nginx
comparison src/http/ngx_http_request.c @ 6961:903fb1ddc07f
Moved handling of wev->delayed to the connection event handler.
With post_action or subrequests, it is possible that the timer set for
wev->delayed will expire while the active subrequest write event handler
is not ready to handle this. This results in request hangs as observed
with limit_rate / sendfile_max_chunk and post_action (ticket #776) or
subrequests (ticket #1228).
Moving the handling to the connection event handler fixes the hangs observed,
and also slightly simplifies the code.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Sun, 02 Apr 2017 14:32:29 +0300 |
parents | 1c43ac026c1d |
children | 5d3d9b52327d |
comparison
equal
deleted
inserted
replaced
6960:1c5e5e5b008d | 6961:903fb1ddc07f |
---|---|
2196 ngx_http_set_log_request(c->log, r); | 2196 ngx_http_set_log_request(c->log, r); |
2197 | 2197 |
2198 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, | 2198 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, |
2199 "http run request: \"%V?%V\"", &r->uri, &r->args); | 2199 "http run request: \"%V?%V\"", &r->uri, &r->args); |
2200 | 2200 |
2201 if (ev->delayed && ev->timedout) { | |
2202 ev->delayed = 0; | |
2203 ev->timedout = 0; | |
2204 } | |
2205 | |
2201 if (ev->write) { | 2206 if (ev->write) { |
2202 r->write_event_handler(r); | 2207 r->write_event_handler(r); |
2203 | 2208 |
2204 } else { | 2209 } else { |
2205 r->read_event_handler(r); | 2210 r->read_event_handler(r); |
2619 "http writer handler: \"%V?%V\"", &r->uri, &r->args); | 2624 "http writer handler: \"%V?%V\"", &r->uri, &r->args); |
2620 | 2625 |
2621 clcf = ngx_http_get_module_loc_conf(r->main, ngx_http_core_module); | 2626 clcf = ngx_http_get_module_loc_conf(r->main, ngx_http_core_module); |
2622 | 2627 |
2623 if (wev->timedout) { | 2628 if (wev->timedout) { |
2624 if (!wev->delayed) { | 2629 ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, |
2625 ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, | 2630 "client timed out"); |
2626 "client timed out"); | 2631 c->timedout = 1; |
2627 c->timedout = 1; | 2632 |
2628 | 2633 ngx_http_finalize_request(r, NGX_HTTP_REQUEST_TIME_OUT); |
2629 ngx_http_finalize_request(r, NGX_HTTP_REQUEST_TIME_OUT); | 2634 return; |
2630 return; | |
2631 } | |
2632 | |
2633 wev->timedout = 0; | |
2634 wev->delayed = 0; | |
2635 | |
2636 if (!wev->ready) { | |
2637 ngx_add_timer(wev, clcf->send_timeout); | |
2638 | |
2639 if (ngx_handle_write_event(wev, clcf->send_lowat) != NGX_OK) { | |
2640 ngx_http_close_request(r, 0); | |
2641 } | |
2642 | |
2643 return; | |
2644 } | |
2645 | |
2646 } | 2635 } |
2647 | 2636 |
2648 if (wev->delayed || r->aio) { | 2637 if (wev->delayed || r->aio) { |
2649 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, wev->log, 0, | 2638 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, wev->log, 0, |
2650 "http writer delayed"); | 2639 "http writer delayed"); |
2640 | |
2641 if (!wev->delayed) { | |
2642 ngx_add_timer(wev, clcf->send_timeout); | |
2643 } | |
2651 | 2644 |
2652 if (ngx_handle_write_event(wev, clcf->send_lowat) != NGX_OK) { | 2645 if (ngx_handle_write_event(wev, clcf->send_lowat) != NGX_OK) { |
2653 ngx_http_close_request(r, 0); | 2646 ngx_http_close_request(r, 0); |
2654 } | 2647 } |
2655 | 2648 |