Mercurial > hg > nginx
comparison src/http/ngx_http_spdy.c @ 5493:916cb6d28f6a
SPDY: fixed possible request hang.
Processing events from upstream connection can result in sending queued frames
from other streams. In this case such streams were not added to handling queue
and properly handled.
A global per connection flag was replaced by a per stream flag that indicates
currently sending stream while all other streams can be added to handling
queue.
author | Valentin Bartenev <vbart@nginx.com> |
---|---|
date | Thu, 26 Dec 2013 17:03:16 +0400 |
parents | a279d2a33dbf |
children | a30bba3c72e8 |
comparison
equal
deleted
inserted
replaced
5492:5c52ff68f380 | 5493:916cb6d28f6a |
---|---|
409 return; | 409 return; |
410 } | 410 } |
411 | 411 |
412 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "spdy write handler"); | 412 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "spdy write handler"); |
413 | 413 |
414 sc->blocked = 2; | 414 sc->blocked = 1; |
415 | 415 |
416 rc = ngx_http_spdy_send_output_queue(sc); | 416 rc = ngx_http_spdy_send_output_queue(sc); |
417 | 417 |
418 if (rc == NGX_ERROR) { | 418 if (rc == NGX_ERROR) { |
419 ngx_http_spdy_finalize_connection(sc, NGX_HTTP_CLIENT_CLOSED_REQUEST); | 419 ngx_http_spdy_finalize_connection(sc, NGX_HTTP_CLIENT_CLOSED_REQUEST); |
427 s->next = stream; | 427 s->next = stream; |
428 stream = s; | 428 stream = s; |
429 } | 429 } |
430 | 430 |
431 sc->last_stream = NULL; | 431 sc->last_stream = NULL; |
432 | |
433 sc->blocked = 1; | |
434 | 432 |
435 for ( /* void */ ; stream; stream = sn) { | 433 for ( /* void */ ; stream; stream = sn) { |
436 sn = stream->next; | 434 sn = stream->next; |
437 stream->handled = 0; | 435 stream->handled = 0; |
438 | 436 |
2656 { | 2654 { |
2657 sc->connection->error = 1; | 2655 sc->connection->error = 1; |
2658 } | 2656 } |
2659 } | 2657 } |
2660 | 2658 |
2659 if (stream->handled) { | |
2660 for (s = sc->last_stream; s; s = s->next) { | |
2661 if (s->next == stream) { | |
2662 s->next = stream->next; | |
2663 break; | |
2664 } | |
2665 } | |
2666 } | |
2667 | |
2661 sscf = ngx_http_get_module_srv_conf(sc->http_connection->conf_ctx, | 2668 sscf = ngx_http_get_module_srv_conf(sc->http_connection->conf_ctx, |
2662 ngx_http_spdy_module); | 2669 ngx_http_spdy_module); |
2663 | 2670 |
2664 index = sc->streams_index + ngx_http_spdy_stream_index(sscf, stream->id); | 2671 index = sc->streams_index + ngx_http_spdy_stream_index(sscf, stream->id); |
2665 | 2672 |
2845 | 2852 |
2846 for (i = 0; i < size; i++) { | 2853 for (i = 0; i < size; i++) { |
2847 stream = sc->streams_index[i]; | 2854 stream = sc->streams_index[i]; |
2848 | 2855 |
2849 while (stream) { | 2856 while (stream) { |
2857 stream->handled = 0; | |
2858 | |
2850 r = stream->request; | 2859 r = stream->request; |
2851 | |
2852 fc = r->connection; | 2860 fc = r->connection; |
2861 | |
2853 fc->error = 1; | 2862 fc->error = 1; |
2854 | 2863 |
2855 if (stream->waiting) { | 2864 if (stream->waiting) { |
2856 r->blocked -= stream->waiting; | 2865 r->blocked -= stream->waiting; |
2857 stream->waiting = 0; | 2866 stream->waiting = 0; |