]> git.kaiwu.me - nginx.git/commitdiff
Stream: postpone session initialization under accept mutex.
authorDmitry Volyntsev <xeioex@nginx.com>
Tue, 6 Sep 2016 18:28:13 +0000 (21:28 +0300)
committerDmitry Volyntsev <xeioex@nginx.com>
Tue, 6 Sep 2016 18:28:13 +0000 (21:28 +0300)
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.

src/stream/ngx_stream.h
src/stream/ngx_stream_handler.c

index 958fca96a0f6677b6024a58ae885e920e1ef3c83..1a7d56864467159e92a409253b7fd6768e9b7a87 100644 (file)
@@ -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
 };
 
 
index 49c58c4e0c7c31b3cdb30d56b78e76deba49a6e7..18fd5f3724c717089b9ff27ddb5f4bb2dd6cd439 100644 (file)
@@ -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_handler(ngx_connection_t *c);
 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_connection_t *c)
     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_connection_t *c)
     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_connection_t *c)
         }
     }
 
+    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_connection_t *c)
 
     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) {