Mercurial > hg > nginx
comparison src/http/ngx_http_spdy.c @ 5923:2c10db908b8c
SPDY: push pending data while closing a stream as with keepalive.
This helps to avoid delays in sending the last chunk of data because
of bad interaction between Nagle's algorithm on nginx side and
delayed ACK on the client side.
Delays could also be caused by TCP_CORK/TCP_NOPUSH if SPDY was
working without SSL and sendfile() was used.
author | Valentin Bartenev <vbart@nginx.com> |
---|---|
date | Fri, 21 Nov 2014 22:51:49 +0300 |
parents | abb466a57a22 |
children | 199c0dd313ea |
comparison
equal
deleted
inserted
replaced
5922:68f64bc17fa4 | 5923:2c10db908b8c |
---|---|
3315 | 3315 |
3316 | 3316 |
3317 void | 3317 void |
3318 ngx_http_spdy_close_stream(ngx_http_spdy_stream_t *stream, ngx_int_t rc) | 3318 ngx_http_spdy_close_stream(ngx_http_spdy_stream_t *stream, ngx_int_t rc) |
3319 { | 3319 { |
3320 int tcp_nodelay; | |
3320 ngx_event_t *ev; | 3321 ngx_event_t *ev; |
3321 ngx_connection_t *fc; | 3322 ngx_connection_t *c, *fc; |
3323 ngx_http_core_loc_conf_t *clcf; | |
3322 ngx_http_spdy_stream_t **index, *s; | 3324 ngx_http_spdy_stream_t **index, *s; |
3323 ngx_http_spdy_srv_conf_t *sscf; | 3325 ngx_http_spdy_srv_conf_t *sscf; |
3324 ngx_http_spdy_connection_t *sc; | 3326 ngx_http_spdy_connection_t *sc; |
3325 | 3327 |
3326 sc = stream->connection; | 3328 sc = stream->connection; |
3341 NGX_SPDY_INTERNAL_ERROR, | 3343 NGX_SPDY_INTERNAL_ERROR, |
3342 stream->priority) | 3344 stream->priority) |
3343 != NGX_OK) | 3345 != NGX_OK) |
3344 { | 3346 { |
3345 sc->connection->error = 1; | 3347 sc->connection->error = 1; |
3348 } | |
3349 | |
3350 } else { | |
3351 c = sc->connection; | |
3352 | |
3353 if (c->tcp_nopush == NGX_TCP_NOPUSH_SET) { | |
3354 if (ngx_tcp_push(c->fd) == -1) { | |
3355 ngx_connection_error(c, ngx_socket_errno, | |
3356 ngx_tcp_push_n " failed"); | |
3357 c->error = 1; | |
3358 tcp_nodelay = 0; | |
3359 | |
3360 } else { | |
3361 c->tcp_nopush = NGX_TCP_NOPUSH_UNSET; | |
3362 tcp_nodelay = ngx_tcp_nodelay_and_tcp_nopush ? 1 : 0; | |
3363 } | |
3364 | |
3365 } else { | |
3366 tcp_nodelay = 1; | |
3367 } | |
3368 | |
3369 clcf = ngx_http_get_module_loc_conf(stream->request, | |
3370 ngx_http_core_module); | |
3371 | |
3372 if (tcp_nodelay | |
3373 && clcf->tcp_nodelay | |
3374 && c->tcp_nodelay == NGX_TCP_NODELAY_UNSET) | |
3375 { | |
3376 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "tcp_nodelay"); | |
3377 | |
3378 if (setsockopt(c->fd, IPPROTO_TCP, TCP_NODELAY, | |
3379 (const void *) &tcp_nodelay, sizeof(int)) | |
3380 == -1) | |
3381 { | |
3382 #if (NGX_SOLARIS) | |
3383 /* Solaris returns EINVAL if a socket has been shut down */ | |
3384 c->log_error = NGX_ERROR_IGNORE_EINVAL; | |
3385 #endif | |
3386 | |
3387 ngx_connection_error(c, ngx_socket_errno, | |
3388 "setsockopt(TCP_NODELAY) failed"); | |
3389 | |
3390 c->log_error = NGX_ERROR_INFO; | |
3391 c->error = 1; | |
3392 | |
3393 } else { | |
3394 c->tcp_nodelay = NGX_TCP_NODELAY_SET; | |
3395 } | |
3346 } | 3396 } |
3347 } | 3397 } |
3348 | 3398 |
3349 if (sc->stream == stream) { | 3399 if (sc->stream == stream) { |
3350 sc->stream = NULL; | 3400 sc->stream = NULL; |