Mercurial > hg > nginx-quic
comparison src/event/ngx_event_accept.c @ 4665:25611746fee7 stable-1.2
Merge of r4619: accept moderation on EMFILE/ENFILE.
In case of EMFILE/ENFILE returned from accept() we disable accept events,
and (in case of no accept mutex used) arm timer to re-enable them later.
With accept mutex we just drop it, and rely on normal accept mutex handling
to re-enable accept events once it's acquired again.
As we now handle errors in question, logging level was changed to "crit"
(instead of "alert" used for unknown errors).
Note: the code might call ngx_enable_accept_events() multiple times if
there are many listen sockets. The ngx_enable_accept_events() function was
modified to check if connection is already active (via c->read->active) and
skip it then, thus making multiple calls safe.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Mon, 04 Jun 2012 11:10:36 +0000 |
parents | d620f497c50f |
children | ba2c7463ce18 |
comparison
equal
deleted
inserted
replaced
4664:356c91151658 | 4665:25611746fee7 |
---|---|
19 ngx_event_accept(ngx_event_t *ev) | 19 ngx_event_accept(ngx_event_t *ev) |
20 { | 20 { |
21 socklen_t socklen; | 21 socklen_t socklen; |
22 ngx_err_t err; | 22 ngx_err_t err; |
23 ngx_log_t *log; | 23 ngx_log_t *log; |
24 ngx_uint_t level; | |
24 ngx_socket_t s; | 25 ngx_socket_t s; |
25 ngx_event_t *rev, *wev; | 26 ngx_event_t *rev, *wev; |
26 ngx_listening_t *ls; | 27 ngx_listening_t *ls; |
27 ngx_connection_t *c, *lc; | 28 ngx_connection_t *c, *lc; |
28 ngx_event_conf_t *ecf; | 29 ngx_event_conf_t *ecf; |
29 u_char sa[NGX_SOCKADDRLEN]; | 30 u_char sa[NGX_SOCKADDRLEN]; |
30 #if (NGX_HAVE_ACCEPT4) | 31 #if (NGX_HAVE_ACCEPT4) |
31 static ngx_uint_t use_accept4 = 1; | 32 static ngx_uint_t use_accept4 = 1; |
32 #endif | 33 #endif |
33 | 34 |
35 if (ev->timedout) { | |
36 if (ngx_enable_accept_events((ngx_cycle_t *) ngx_cycle) != NGX_OK) { | |
37 return; | |
38 } | |
39 | |
40 ev->timedout = 0; | |
41 } | |
42 | |
34 ecf = ngx_event_get_conf(ngx_cycle->conf_ctx, ngx_event_core_module); | 43 ecf = ngx_event_get_conf(ngx_cycle->conf_ctx, ngx_event_core_module); |
35 | 44 |
36 if (ngx_event_flags & NGX_USE_RTSIG_EVENT) { | 45 if (ngx_event_flags & NGX_USE_RTSIG_EVENT) { |
37 ev->available = 1; | 46 ev->available = 1; |
38 | 47 |
68 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ev->log, err, | 77 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ev->log, err, |
69 "accept() not ready"); | 78 "accept() not ready"); |
70 return; | 79 return; |
71 } | 80 } |
72 | 81 |
82 level = NGX_LOG_ALERT; | |
83 | |
84 if (err == NGX_ECONNABORTED) { | |
85 level = NGX_LOG_ERR; | |
86 | |
87 } else if (err == NGX_EMFILE || err == NGX_ENFILE) { | |
88 level = NGX_LOG_CRIT; | |
89 } | |
90 | |
73 #if (NGX_HAVE_ACCEPT4) | 91 #if (NGX_HAVE_ACCEPT4) |
74 ngx_log_error((ngx_uint_t) ((err == NGX_ECONNABORTED) ? | 92 ngx_log_error(level, ev->log, err, |
75 NGX_LOG_ERR : NGX_LOG_ALERT), | |
76 ev->log, err, | |
77 use_accept4 ? "accept4() failed" : "accept() failed"); | 93 use_accept4 ? "accept4() failed" : "accept() failed"); |
78 | 94 |
79 if (use_accept4 && err == NGX_ENOSYS) { | 95 if (use_accept4 && err == NGX_ENOSYS) { |
80 use_accept4 = 0; | 96 use_accept4 = 0; |
81 ngx_inherited_nonblocking = 0; | 97 ngx_inherited_nonblocking = 0; |
82 continue; | 98 continue; |
83 } | 99 } |
84 #else | 100 #else |
85 ngx_log_error((ngx_uint_t) ((err == NGX_ECONNABORTED) ? | 101 ngx_log_error(level, ev->log, err, "accept() failed"); |
86 NGX_LOG_ERR : NGX_LOG_ALERT), | |
87 ev->log, err, "accept() failed"); | |
88 #endif | 102 #endif |
89 | 103 |
90 if (err == NGX_ECONNABORTED) { | 104 if (err == NGX_ECONNABORTED) { |
91 if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) { | 105 if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) { |
92 ev->available--; | 106 ev->available--; |
93 } | 107 } |
94 | 108 |
95 if (ev->available) { | 109 if (ev->available) { |
96 continue; | 110 continue; |
111 } | |
112 } | |
113 | |
114 if (err == NGX_EMFILE || err == NGX_ENFILE) { | |
115 if (ngx_disable_accept_events((ngx_cycle_t *) ngx_cycle) | |
116 != NGX_OK) | |
117 { | |
118 return; | |
119 } | |
120 | |
121 if (ngx_use_accept_mutex) { | |
122 if (ngx_accept_mutex_held) { | |
123 ngx_shmtx_unlock(&ngx_accept_mutex); | |
124 ngx_accept_mutex_held = 0; | |
125 } | |
126 | |
127 ngx_accept_disabled = 1; | |
128 | |
129 } else { | |
130 ngx_add_timer(ev, ecf->accept_mutex_delay); | |
97 } | 131 } |
98 } | 132 } |
99 | 133 |
100 return; | 134 return; |
101 } | 135 } |
342 ls = cycle->listening.elts; | 376 ls = cycle->listening.elts; |
343 for (i = 0; i < cycle->listening.nelts; i++) { | 377 for (i = 0; i < cycle->listening.nelts; i++) { |
344 | 378 |
345 c = ls[i].connection; | 379 c = ls[i].connection; |
346 | 380 |
381 if (c->read->active) { | |
382 continue; | |
383 } | |
384 | |
347 if (ngx_event_flags & NGX_USE_RTSIG_EVENT) { | 385 if (ngx_event_flags & NGX_USE_RTSIG_EVENT) { |
348 | 386 |
349 if (ngx_add_conn(c) == NGX_ERROR) { | 387 if (ngx_add_conn(c) == NGX_ERROR) { |
350 return NGX_ERROR; | 388 return NGX_ERROR; |
351 } | 389 } |