Welcome! Log In Create A New Profile

Advanced

[PATCH] Fix nopush cleanup for SPDY

Yury Kirpichev
June 11, 2013 05:02AM
Hi,

Could you please take a look at patch below.
I've tried to fix problem that TCP_CORK option is not cleaned in SPDY case.

# HG changeset patch
# User ykirpichev@gmail.com
# Date 1370939502 -14400
# Branch nopush_fix_1
# Node ID 58d7a76b975ed7afb6a980b8810051a10dfc96f4
# Parent 725fb71ab1a60bd48b0afb8b001b5349f5054cb1
Fix tcp_nopush cleanup for spdy

diff -r 725fb71ab1a6 -r 58d7a76b975e src/http/ngx_http.c
--- a/src/http/ngx_http.c Fri Jun 07 13:16:00 2013 -0700
+++ b/src/http/ngx_http.c Tue Jun 11 12:31:42 2013 +0400
@@ -2106,3 +2106,112 @@

return NGX_OK;
}
+
+
+ngx_int_t
+ngx_http_check_and_set_nopush(ngx_connection_t* c)
+{
+ int tcp_nodelay;
+
+ /* the TCP_CORK and TCP_NODELAY are mutually exclusive */
+ if (c->tcp_nodelay == NGX_TCP_NODELAY_SET) {
+
+ tcp_nodelay = 0;
+
+ if (setsockopt(c->fd, IPPROTO_TCP, TCP_NODELAY,
+ (const void *) &tcp_nodelay, sizeof(int)) == -1)
+ {
+ /*
+ * there is a tiny chance to be interrupted, however,
+ * we continue a processing with the TCP_NODELAY
+ * and without the TCP_CORK
+ */
+
+ if (ngx_errno != NGX_EINTR) {
+ ngx_connection_error(c, ngx_errno,
+ "setsockopt(TCP_NODELAY) failed");
+ return NGX_ERROR;
+ }
+
+ } else {
+ c->tcp_nodelay = NGX_TCP_NODELAY_UNSET;
+
+ ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
+ "no tcp_nodelay");
+ }
+ }
+
+ if (c->tcp_nodelay == NGX_TCP_NODELAY_UNSET) {
+
+ if (ngx_tcp_nopush(c->fd) == NGX_ERROR) {
+
+ /*
+ * there is a tiny chance to be interrupted, however,
+ * we continue a processing without the TCP_CORK
+ */
+
+ if (ngx_errno != NGX_EINTR) {
+ ngx_connection_error(c, ngx_errno,
+ ngx_tcp_nopush_n " failed");
+ return NGX_ERROR;
+ }
+
+ } else {
+ c->tcp_nopush = NGX_TCP_NOPUSH_SET;
+
+ ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
+ "tcp_nopush");
+ }
+ }
+
+ return NGX_OK;
+}
+
+ngx_int_t
+ngx_http_check_and_restore_nopush(ngx_connection_t* c,
+ ngx_http_core_loc_conf_t* clcf)
+{
+ int tcp_nodelay;
+
+ if (c->tcp_nopush == NGX_TCP_NOPUSH_SET) {
+ if (ngx_tcp_push(c->fd) == -1) {
+ ngx_connection_error(c, ngx_socket_errno, ngx_tcp_push_n "
failed");
+ return NGX_ERROR;
+ }
+
+ c->tcp_nopush = NGX_TCP_NOPUSH_UNSET;
+ tcp_nodelay = ngx_tcp_nodelay_and_tcp_nopush ? 1 : 0;
+
+ } else {
+ tcp_nodelay = 1;
+ }
+#if 1
+ if (tcp_nodelay
+ && clcf->tcp_nodelay
+ && c->tcp_nodelay == NGX_TCP_NODELAY_UNSET)
+ {
+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "tcp_nodelay");
+
+ if (setsockopt(c->fd, IPPROTO_TCP, TCP_NODELAY,
+ (const void *) &tcp_nodelay, sizeof(int))
+ == -1)
+ {
+#if (NGX_SOLARIS)
+ /* Solaris returns EINVAL if a socket has been shut down */
+ c->log_error = NGX_ERROR_IGNORE_EINVAL;
+#endif
+
+ ngx_connection_error(c, ngx_socket_errno,
+ "setsockopt(TCP_NODELAY) failed");
+
+ c->log_error = NGX_ERROR_INFO;
+ return NGX_ERROR;
+ }
+
+ c->tcp_nodelay = NGX_TCP_NODELAY_SET;
+ }
+#endif
+
+ return NGX_OK;
+}
+
diff -r 725fb71ab1a6 -r 58d7a76b975e src/http/ngx_http.h
--- a/src/http/ngx_http.h Fri Jun 07 13:16:00 2013 -0700
+++ b/src/http/ngx_http.h Tue Jun 11 12:31:42 2013 +0400
@@ -180,5 +180,9 @@
extern ngx_http_output_header_filter_pt ngx_http_top_header_filter;
extern ngx_http_output_body_filter_pt ngx_http_top_body_filter;

+ngx_int_t ngx_http_check_and_set_nopush(ngx_connection_t* c);
+
+ngx_int_t ngx_http_check_and_restore_nopush(ngx_connection_t* c,
+ ngx_http_core_loc_conf_t*
clcf);

#endif /* _NGX_HTTP_H_INCLUDED_ */
diff -r 725fb71ab1a6 -r 58d7a76b975e src/http/ngx_http_request.c
--- a/src/http/ngx_http_request.c Fri Jun 07 13:16:00 2013 -0700
+++ b/src/http/ngx_http_request.c Tue Jun 11 12:31:42 2013 +0400
@@ -2740,7 +2740,6 @@
static void
ngx_http_set_keepalive(ngx_http_request_t *r)
{
- int tcp_nodelay;
ngx_int_t i;
ngx_buf_t *b, *f;
ngx_event_t *rev, *wev;
@@ -2913,44 +2912,9 @@

c->log->action = "keepalive";

- if (c->tcp_nopush == NGX_TCP_NOPUSH_SET) {
- if (ngx_tcp_push(c->fd) == -1) {
- ngx_connection_error(c, ngx_socket_errno, ngx_tcp_push_n "
failed");
- ngx_http_close_connection(c);
- return;
- }
-
- c->tcp_nopush = NGX_TCP_NOPUSH_UNSET;
- tcp_nodelay = ngx_tcp_nodelay_and_tcp_nopush ? 1 : 0;
-
- } else {
- tcp_nodelay = 1;
- }
-
- if (tcp_nodelay
- && clcf->tcp_nodelay
- && c->tcp_nodelay == NGX_TCP_NODELAY_UNSET)
- {
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "tcp_nodelay");
-
- if (setsockopt(c->fd, IPPROTO_TCP, TCP_NODELAY,
- (const void *) &tcp_nodelay, sizeof(int))
- == -1)
- {
-#if (NGX_SOLARIS)
- /* Solaris returns EINVAL if a socket has been shut down */
- c->log_error = NGX_ERROR_IGNORE_EINVAL;
-#endif
-
- ngx_connection_error(c, ngx_socket_errno,
- "setsockopt(TCP_NODELAY) failed");
-
- c->log_error = NGX_ERROR_INFO;
- ngx_http_close_connection(c);
- return;
- }
-
- c->tcp_nodelay = NGX_TCP_NODELAY_SET;
+ if (ngx_http_check_and_restore_nopush(c, clcf) != NGX_OK) {
+ ngx_http_close_connection(c);
+ return;
}

#if 0
diff -r 725fb71ab1a6 -r 58d7a76b975e src/http/ngx_http_spdy.c
--- a/src/http/ngx_http_spdy.c Fri Jun 07 13:16:00 2013 -0700
+++ b/src/http/ngx_http_spdy.c Tue Jun 11 12:31:42 2013 +0400
@@ -450,7 +450,6 @@
ngx_http_spdy_handle_connection(sc);
}

-
ngx_int_t
ngx_http_spdy_send_output_queue(ngx_http_spdy_connection_t *sc)
{
@@ -490,6 +489,13 @@
}

cl = c->send_chain(c, cl, 0);
+ clcf = ngx_http_get_module_loc_conf(sc->http_connection->conf_ctx,
+ ngx_http_core_module);
+
+ if (ngx_http_check_and_restore_nopush(c, clcf) != NGX_OK) {
+ c->error = 1;
+ return NGX_ERROR;
+ }

if (cl == NGX_CHAIN_ERROR) {
c->error = 1;
@@ -501,8 +507,6 @@
return NGX_ERROR;
}

- clcf = ngx_http_get_module_loc_conf(sc->http_connection->conf_ctx,
- ngx_http_core_module);

if (ngx_handle_write_event(wev, clcf->send_lowat) != NGX_OK) {
return NGX_ERROR; /* FIXME */
diff -r 725fb71ab1a6 -r 58d7a76b975e src/os/unix/ngx_linux_sendfile_chain.c
--- a/src/os/unix/ngx_linux_sendfile_chain.c Fri Jun 07 13:16:00 2013 -0700
+++ b/src/os/unix/ngx_linux_sendfile_chain.c Tue Jun 11 12:31:42 2013 +0400
@@ -33,11 +33,13 @@
#define NGX_HEADERS IOV_MAX
#endif

+ngx_int_t
+ngx_http_check_and_set_nopush(ngx_connection_t* c);

ngx_chain_t *
ngx_linux_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
{
- int rc, tcp_nodelay;
+ int rc;
off_t size, send, prev_send, aligned, sent, fprev;
u_char *prev;
size_t file_size;
@@ -154,61 +156,9 @@
&& cl
&& cl->buf->in_file)
{
- /* the TCP_CORK and TCP_NODELAY are mutually exclusive */
-
- if (c->tcp_nodelay == NGX_TCP_NODELAY_SET) {
-
- tcp_nodelay = 0;
-
- if (setsockopt(c->fd, IPPROTO_TCP, TCP_NODELAY,
- (const void *) &tcp_nodelay, sizeof(int))
== -1)
- {
- err = ngx_errno;
-
- /*
- * there is a tiny chance to be interrupted, however,
- * we continue a processing with the TCP_NODELAY
- * and without the TCP_CORK
- */
-
- if (err != NGX_EINTR) {
- wev->error = 1;
- ngx_connection_error(c, err,
- "setsockopt(TCP_NODELAY)
failed");
- return NGX_CHAIN_ERROR;
- }
-
- } else {
- c->tcp_nodelay = NGX_TCP_NODELAY_UNSET;
-
- ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
- "no tcp_nodelay");
- }
- }
-
- if (c->tcp_nodelay == NGX_TCP_NODELAY_UNSET) {
-
- if (ngx_tcp_nopush(c->fd) == NGX_ERROR) {
- err = ngx_errno;
-
- /*
- * there is a tiny chance to be interrupted, however,
- * we continue a processing without the TCP_CORK
- */
-
- if (err != NGX_EINTR) {
- wev->error = 1;
- ngx_connection_error(c, err,
- ngx_tcp_nopush_n " failed");
- return NGX_CHAIN_ERROR;
- }
-
- } else {
- c->tcp_nopush = NGX_TCP_NOPUSH_SET;
-
- ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
- "tcp_nopush");
- }
+ if (ngx_http_check_and_set_nopush(c) != NGX_OK) {
+ wev->error = 1;
+ return NGX_CHAIN_ERROR;
}
}
_______________________________________________
nginx-devel mailing list
nginx-devel@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-devel
Subject Author Views Posted

[PATCH] Fix nopush cleanup for SPDY Attachments

Yury Kirpichev 866 June 11, 2013 05:02AM

Re: [PATCH] Fix nopush cleanup for SPDY

Maxim Dounin 372 June 11, 2013 08:14AM



Sorry, you do not have permission to post/reply in this forum.

Online Users

Guests: 192
Record Number of Users: 8 on April 13, 2023
Record Number of Guests: 421 on December 02, 2018
Powered by nginx      Powered by FreeBSD      PHP Powered      Powered by MariaDB      ipv6 ready