[nginx] Stream: postpone session initialization under accept mutex.

Dmitry Volyntsev xeioex at nginx.com
Wed Sep 7 15:28:41 UTC 2016


details:   http://hg.nginx.org/nginx/rev/40e8ce405859
branches:  
changeset: 6679:40e8ce405859
user:      Dmitry Volyntsev <xeioex at nginx.com>
date:      Tue Sep 06 21:28:13 2016 +0300
description:
Stream: postpone session initialization under accept mutex.

Previously, it was possible that some system calls could be
invoked while holding the accept mutex.  This is clearly
wrong as it prevents incoming connections from being accepted
as quickly as possible.

diffstat:

 src/stream/ngx_stream.h         |   4 ++++
 src/stream/ngx_stream_handler.c |  41 ++++++++++++++++++++++++++++++++++++++---
 2 files changed, 42 insertions(+), 3 deletions(-)

diffs (104 lines):

diff -r 0125b151c9a5 -r 40e8ce405859 src/stream/ngx_stream.h
--- a/src/stream/ngx_stream.h	Mon Sep 05 17:50:16 2016 +0300
+++ b/src/stream/ngx_stream.h	Tue Sep 06 21:28:13 2016 +0300
@@ -184,6 +184,10 @@ struct ngx_stream_session_s {
 #endif
 
     ngx_uint_t                     status;
+
+#if (NGX_STREAM_SSL)
+    ngx_uint_t                     ssl;  /* unsigned  ssl:1; */
+#endif
 };
 
 
diff -r 0125b151c9a5 -r 40e8ce405859 src/stream/ngx_stream_handler.c
--- a/src/stream/ngx_stream_handler.c	Mon Sep 05 17:50:16 2016 +0300
+++ b/src/stream/ngx_stream_handler.c	Tue Sep 06 21:28:13 2016 +0300
@@ -13,6 +13,7 @@
 
 static void ngx_stream_close_connection(ngx_connection_t *c);
 static u_char *ngx_stream_log_error(ngx_log_t *log, u_char *buf, size_t len);
+static void ngx_stream_init_session_handler(ngx_event_t *rev);
 static void ngx_stream_init_session(ngx_connection_t *c);
 
 #if (NGX_STREAM_SSL)
@@ -24,12 +25,11 @@ static void ngx_stream_ssl_handshake_han
 void
 ngx_stream_init_connection(ngx_connection_t *c)
 {
-    int                           tcp_nodelay;
     u_char                        text[NGX_SOCKADDR_STRLEN];
     size_t                        len;
-    ngx_int_t                     rc;
     ngx_uint_t                    i;
     ngx_time_t                   *tp;
+    ngx_event_t                  *rev;
     struct sockaddr              *sa;
     ngx_stream_port_t            *port;
     struct sockaddr_in           *sin;
@@ -130,6 +130,10 @@ ngx_stream_init_connection(ngx_connectio
     s->main_conf = addr_conf->ctx->main_conf;
     s->srv_conf = addr_conf->ctx->srv_conf;
 
+#if (NGX_STREAM_SSL)
+    s->ssl = addr_conf->ssl;
+#endif
+
     s->connection = c;
     c->data = s;
 
@@ -164,6 +168,35 @@ ngx_stream_init_connection(ngx_connectio
     s->start_sec = tp->sec;
     s->start_msec = tp->msec;
 
+    rev = c->read;
+    rev->handler = ngx_stream_init_session_handler;
+
+    if (ngx_use_accept_mutex) {
+        ngx_post_event(rev, &ngx_posted_events);
+        return;
+    }
+
+    rev->handler(rev);
+}
+
+
+static void
+ngx_stream_init_session_handler(ngx_event_t *rev)
+{
+    int                           tcp_nodelay;
+    ngx_int_t                     rc;
+    ngx_connection_t             *c;
+    ngx_stream_session_t         *s;
+    ngx_stream_core_srv_conf_t   *cscf;
+    ngx_stream_core_main_conf_t  *cmcf;
+
+    c = rev->data;
+    s = c->data;
+
+    c->log->action = "initializing session";
+
+    cmcf = ngx_stream_get_module_main_conf(s, ngx_stream_core_module);
+
     if (cmcf->limit_conn_handler) {
         rc = cmcf->limit_conn_handler(s);
 
@@ -192,6 +225,8 @@ ngx_stream_init_connection(ngx_connectio
         }
     }
 
+    cscf = ngx_stream_get_module_srv_conf(s, ngx_stream_core_module);
+
     if (c->type == SOCK_STREAM
         && cscf->tcp_nodelay
         && c->tcp_nodelay == NGX_TCP_NODELAY_UNSET)
@@ -219,7 +254,7 @@ ngx_stream_init_connection(ngx_connectio
 
     sslcf = ngx_stream_get_module_srv_conf(s, ngx_stream_ssl_module);
 
-    if (addr_conf->ssl) {
+    if (s->ssl) {
         c->log->action = "SSL handshaking";
 
         if (sslcf->ssl.ctx == NULL) {



More information about the nginx-devel mailing list