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.
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "spdy write handler");
- sc->blocked = 2;
+ sc->blocked = 1;
rc = ngx_http_spdy_send_output_queue(sc);
sc->last_stream = NULL;
- sc->blocked = 1;
-
for ( /* void */ ; stream; stream = sn) {
sn = stream->next;
stream->handled = 0;
}
}
+ if (stream->handled) {
+ for (s = sc->last_stream; s; s = s->next) {
+ if (s->next == stream) {
+ s->next = stream->next;
+ break;
+ }
+ }
+ }
+
sscf = ngx_http_get_module_srv_conf(sc->http_connection->conf_ctx,
ngx_http_spdy_module);
stream = sc->streams_index[i];
while (stream) {
- r = stream->request;
+ stream->handled = 0;
+ r = stream->request;
fc = r->connection;
+
fc->error = 1;
if (stream->waiting) {
ngx_uint_t last_sid;
- unsigned blocked:2;
+ unsigned blocked:1;
unsigned waiting:1; /* FIXME better name */
};
unsigned priority:2;
unsigned handled:1;
+ unsigned blocked:1;
unsigned in_closed:1;
unsigned out_closed:1;
unsigned skip_data:2;
static ngx_inline ngx_int_t
ngx_http_spdy_filter_send(ngx_connection_t *fc, ngx_http_spdy_stream_t *stream)
{
+ stream->blocked = 1;
+
if (ngx_http_spdy_send_output_queue(stream->connection) == NGX_ERROR) {
fc->error = 1;
return NGX_ERROR;
}
+ stream->blocked = 0;
+
if (stream->waiting) {
fc->buffered |= NGX_SPDY_WRITE_BUFFERED;
fc->write->delayed = 1;
fc->write->delayed = 0;
- if (stream->handled) {
+ if (stream->handled || stream->blocked) {
return;
}
- if (sc->blocked == 2) {
- stream->handled = 1;
+ stream->handled = 1;
- stream->next = sc->last_stream;
- sc->last_stream = stream;
- }
+ stream->next = sc->last_stream;
+ sc->last_stream = stream;
}