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