# HG changeset patch # User Valentin Bartenev # Date 1389702285 -14400 # Node ID 3ff29c30effbd3772f02afcf39f92cd27f468e51 # Parent 877a7bd72070d928d9f8beb1875f097735c60d3e SPDY: elimination of r->blocked counter usage for queuing frames. It was used to prevent destroying of request object when there are unsent frames in queue for the stream. Since it was incremented for each frame and is only 8 bits long, so it was not very hard to overflow the counter. Now the stream->queued counter is checked instead. diff --git a/src/http/ngx_http_spdy.c b/src/http/ngx_http_spdy.c --- a/src/http/ngx_http_spdy.c +++ b/src/http/ngx_http_spdy.c @@ -2642,9 +2642,16 @@ ngx_http_spdy_close_stream(ngx_http_spdy sc = stream->connection; - ngx_log_debug2(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0, - "spdy close stream %ui, processing %ui", - stream->id, sc->processing); + ngx_log_debug3(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0, + "spdy close stream %ui, queued %ui, processing %ui", + stream->id, stream->queued, sc->processing); + + fc = stream->request->connection; + + if (stream->queued) { + fc->write->handler = ngx_http_spdy_close_stream_handler; + return; + } if (!stream->out_closed) { if (ngx_http_spdy_send_rst_stream(sc, stream->id, @@ -2685,8 +2692,6 @@ ngx_http_spdy_close_stream(ngx_http_spdy index = &s->index; } - fc = stream->request->connection; - ngx_http_free_request(stream->request, rc); ev = fc->read; @@ -2862,7 +2867,6 @@ ngx_http_spdy_finalize_connection(ngx_ht fc->error = 1; if (stream->queued) { - r->blocked -= stream->queued; stream->queued = 0; ev = fc->write; diff --git a/src/http/ngx_http_spdy_filter_module.c b/src/http/ngx_http_spdy_filter_module.c --- a/src/http/ngx_http_spdy_filter_module.c +++ b/src/http/ngx_http_spdy_filter_module.c @@ -597,8 +597,6 @@ ngx_http_spdy_header_filter(ngx_http_req ngx_http_spdy_queue_blocked_frame(sc, frame); - r->blocked++; - cln = ngx_http_cleanup_add(r, 0); if (cln == NULL) { return NGX_ERROR; @@ -697,8 +695,6 @@ ngx_http_spdy_body_filter(ngx_http_reque stream->queued++; - r->main->blocked++; - return ngx_http_spdy_filter_send(r->connection, stream); } @@ -923,7 +919,6 @@ ngx_http_spdy_handle_frame(ngx_http_spdy r = stream->request; r->connection->sent += frame->size; - r->blocked--; if (frame->fin) { stream->out_closed = 1; @@ -962,15 +957,12 @@ ngx_http_spdy_filter_cleanup(void *data) { ngx_http_spdy_stream_t *stream = data; - ngx_http_request_t *r; ngx_http_spdy_out_frame_t *frame, **fn; if (stream->queued == 0) { return; } - r = stream->request; - fn = &stream->connection->last_out; for ( ;; ) { @@ -981,9 +973,7 @@ ngx_http_spdy_filter_cleanup(void *data) } if (frame->stream == stream && !frame->blocked) { - stream->queued--; - r->blocked--; *fn = frame->next; continue;