Mercurial > hg > nginx
comparison src/stream/ngx_stream_handler.c @ 6679:40e8ce405859
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.
author | Dmitry Volyntsev <xeioex@nginx.com> |
---|---|
date | Tue, 06 Sep 2016 21:28:13 +0300 |
parents | 0125b151c9a5 |
children | 7357abd1fa8c |
comparison
equal
deleted
inserted
replaced
6678:0125b151c9a5 | 6679:40e8ce405859 |
---|---|
11 #include <ngx_stream.h> | 11 #include <ngx_stream.h> |
12 | 12 |
13 | 13 |
14 static void ngx_stream_close_connection(ngx_connection_t *c); | 14 static void ngx_stream_close_connection(ngx_connection_t *c); |
15 static u_char *ngx_stream_log_error(ngx_log_t *log, u_char *buf, size_t len); | 15 static u_char *ngx_stream_log_error(ngx_log_t *log, u_char *buf, size_t len); |
16 static void ngx_stream_init_session_handler(ngx_event_t *rev); | |
16 static void ngx_stream_init_session(ngx_connection_t *c); | 17 static void ngx_stream_init_session(ngx_connection_t *c); |
17 | 18 |
18 #if (NGX_STREAM_SSL) | 19 #if (NGX_STREAM_SSL) |
19 static void ngx_stream_ssl_init_connection(ngx_ssl_t *ssl, ngx_connection_t *c); | 20 static void ngx_stream_ssl_init_connection(ngx_ssl_t *ssl, ngx_connection_t *c); |
20 static void ngx_stream_ssl_handshake_handler(ngx_connection_t *c); | 21 static void ngx_stream_ssl_handshake_handler(ngx_connection_t *c); |
22 | 23 |
23 | 24 |
24 void | 25 void |
25 ngx_stream_init_connection(ngx_connection_t *c) | 26 ngx_stream_init_connection(ngx_connection_t *c) |
26 { | 27 { |
27 int tcp_nodelay; | |
28 u_char text[NGX_SOCKADDR_STRLEN]; | 28 u_char text[NGX_SOCKADDR_STRLEN]; |
29 size_t len; | 29 size_t len; |
30 ngx_int_t rc; | |
31 ngx_uint_t i; | 30 ngx_uint_t i; |
32 ngx_time_t *tp; | 31 ngx_time_t *tp; |
32 ngx_event_t *rev; | |
33 struct sockaddr *sa; | 33 struct sockaddr *sa; |
34 ngx_stream_port_t *port; | 34 ngx_stream_port_t *port; |
35 struct sockaddr_in *sin; | 35 struct sockaddr_in *sin; |
36 ngx_stream_in_addr_t *addr; | 36 ngx_stream_in_addr_t *addr; |
37 ngx_stream_session_t *s; | 37 ngx_stream_session_t *s; |
128 | 128 |
129 s->signature = NGX_STREAM_MODULE; | 129 s->signature = NGX_STREAM_MODULE; |
130 s->main_conf = addr_conf->ctx->main_conf; | 130 s->main_conf = addr_conf->ctx->main_conf; |
131 s->srv_conf = addr_conf->ctx->srv_conf; | 131 s->srv_conf = addr_conf->ctx->srv_conf; |
132 | 132 |
133 #if (NGX_STREAM_SSL) | |
134 s->ssl = addr_conf->ssl; | |
135 #endif | |
136 | |
133 s->connection = c; | 137 s->connection = c; |
134 c->data = s; | 138 c->data = s; |
135 | 139 |
136 cscf = ngx_stream_get_module_srv_conf(s, ngx_stream_core_module); | 140 cscf = ngx_stream_get_module_srv_conf(s, ngx_stream_core_module); |
137 | 141 |
162 | 166 |
163 tp = ngx_timeofday(); | 167 tp = ngx_timeofday(); |
164 s->start_sec = tp->sec; | 168 s->start_sec = tp->sec; |
165 s->start_msec = tp->msec; | 169 s->start_msec = tp->msec; |
166 | 170 |
171 rev = c->read; | |
172 rev->handler = ngx_stream_init_session_handler; | |
173 | |
174 if (ngx_use_accept_mutex) { | |
175 ngx_post_event(rev, &ngx_posted_events); | |
176 return; | |
177 } | |
178 | |
179 rev->handler(rev); | |
180 } | |
181 | |
182 | |
183 static void | |
184 ngx_stream_init_session_handler(ngx_event_t *rev) | |
185 { | |
186 int tcp_nodelay; | |
187 ngx_int_t rc; | |
188 ngx_connection_t *c; | |
189 ngx_stream_session_t *s; | |
190 ngx_stream_core_srv_conf_t *cscf; | |
191 ngx_stream_core_main_conf_t *cmcf; | |
192 | |
193 c = rev->data; | |
194 s = c->data; | |
195 | |
196 c->log->action = "initializing session"; | |
197 | |
198 cmcf = ngx_stream_get_module_main_conf(s, ngx_stream_core_module); | |
199 | |
167 if (cmcf->limit_conn_handler) { | 200 if (cmcf->limit_conn_handler) { |
168 rc = cmcf->limit_conn_handler(s); | 201 rc = cmcf->limit_conn_handler(s); |
169 | 202 |
170 if (rc == NGX_ERROR) { | 203 if (rc == NGX_ERROR) { |
171 ngx_stream_finalize_session(s, NGX_STREAM_INTERNAL_SERVER_ERROR); | 204 ngx_stream_finalize_session(s, NGX_STREAM_INTERNAL_SERVER_ERROR); |
189 if (rc == NGX_ABORT) { | 222 if (rc == NGX_ABORT) { |
190 ngx_stream_finalize_session(s, NGX_STREAM_FORBIDDEN); | 223 ngx_stream_finalize_session(s, NGX_STREAM_FORBIDDEN); |
191 return; | 224 return; |
192 } | 225 } |
193 } | 226 } |
227 | |
228 cscf = ngx_stream_get_module_srv_conf(s, ngx_stream_core_module); | |
194 | 229 |
195 if (c->type == SOCK_STREAM | 230 if (c->type == SOCK_STREAM |
196 && cscf->tcp_nodelay | 231 && cscf->tcp_nodelay |
197 && c->tcp_nodelay == NGX_TCP_NODELAY_UNSET) | 232 && c->tcp_nodelay == NGX_TCP_NODELAY_UNSET) |
198 { | 233 { |
217 { | 252 { |
218 ngx_stream_ssl_conf_t *sslcf; | 253 ngx_stream_ssl_conf_t *sslcf; |
219 | 254 |
220 sslcf = ngx_stream_get_module_srv_conf(s, ngx_stream_ssl_module); | 255 sslcf = ngx_stream_get_module_srv_conf(s, ngx_stream_ssl_module); |
221 | 256 |
222 if (addr_conf->ssl) { | 257 if (s->ssl) { |
223 c->log->action = "SSL handshaking"; | 258 c->log->action = "SSL handshaking"; |
224 | 259 |
225 if (sslcf->ssl.ctx == NULL) { | 260 if (sslcf->ssl.ctx == NULL) { |
226 ngx_log_error(NGX_LOG_ERR, c->log, 0, | 261 ngx_log_error(NGX_LOG_ERR, c->log, 0, |
227 "no \"ssl_certificate\" is defined " | 262 "no \"ssl_certificate\" is defined " |