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;