Mercurial > hg > nginx-quic
comparison src/event/ngx_event_accept.c @ 191:71ce40b3c37b
nginx-0.0.1-2003-11-19-19:26:41 import
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Wed, 19 Nov 2003 16:26:41 +0000 |
parents | 84036764e215 |
children | 31824be1fc66 |
comparison
equal
deleted
inserted
replaced
190:02a715e85df1 | 191:71ce40b3c37b |
---|---|
3 #include <ngx_core.h> | 3 #include <ngx_core.h> |
4 #include <ngx_event.h> | 4 #include <ngx_event.h> |
5 #include <nginx.h> | 5 #include <nginx.h> |
6 | 6 |
7 | 7 |
8 static size_t ngx_accept_log_error(void *data, char *buf, size_t len); | |
9 | |
10 | |
8 void ngx_event_accept(ngx_event_t *ev) | 11 void ngx_event_accept(ngx_event_t *ev) |
9 { | 12 { |
10 int instance; | 13 int instance, accepted; |
11 socklen_t len; | 14 socklen_t len; |
12 struct sockaddr *sa; | 15 struct sockaddr *sa; |
13 ngx_err_t err; | 16 ngx_err_t err; |
14 ngx_pool_t *pool; | 17 ngx_log_t *log; |
15 ngx_socket_t s; | 18 ngx_pool_t *pool; |
16 ngx_event_t *rev, *wev; | 19 ngx_socket_t s; |
17 ngx_connection_t *c, *ls; | 20 ngx_event_t *rev, *wev; |
18 ngx_event_conf_t *ecf; | 21 ngx_connection_t *c, *ls; |
22 ngx_event_conf_t *ecf; | |
19 | 23 |
20 ecf = ngx_event_get_conf(ngx_cycle->conf_ctx, ngx_event_core_module); | 24 ecf = ngx_event_get_conf(ngx_cycle->conf_ctx, ngx_event_core_module); |
21 | 25 |
22 ls = ev->data; | 26 ls = ev->data; |
23 | 27 |
24 ngx_log_debug(ev->log, "ngx_event_accept: accept ready: %d" _ | 28 ngx_log_debug(ev->log, "accept on %s ready: %d" _ |
29 ls->listening->addr_text.data _ | |
25 ev->available); | 30 ev->available); |
26 | 31 |
27 ev->ready = 0; | 32 ev->ready = 0; |
33 accepted = 0; | |
28 | 34 |
29 do { | 35 do { |
30 | 36 |
31 /* | 37 /* |
32 * Create the pool before accept() to avoid copy the sockaddr. | 38 * Create the pool before accept() to avoid copy the sockaddr. |
33 * Although accept() can fail it's an uncommon case | 39 * Although accept() can fail it's an uncommon case |
34 * and the pool can be got from the free pool list | 40 * and besides the pool can be got from the free pool list |
35 */ | 41 */ |
36 | 42 |
37 pool = ngx_create_pool(ls->listening->pool_size, ev->log); | 43 if (!(pool = ngx_create_pool(ls->listening->pool_size, ev->log))) { |
38 if (pool == NULL) { | 44 return; |
39 return; | 45 } |
40 } | 46 |
41 | 47 if (!(sa = ngx_palloc(pool, ls->listening->socklen))) { |
42 sa = ngx_palloc(pool, ls->listening->socklen); | 48 return; |
43 if (sa == NULL) { | 49 } |
44 return; | 50 |
45 } | 51 if (!(log = ngx_palloc(pool, sizeof(ngx_log_t)))) { |
52 return; | |
53 } | |
54 ngx_memcpy(log, ls->log, sizeof(ngx_log_t)); | |
55 pool->log = log; | |
56 | |
57 log->data = ls->listening->addr_text.data; | |
58 log->handler = ngx_accept_log_error; | |
46 | 59 |
47 len = ls->listening->socklen; | 60 len = ls->listening->socklen; |
48 | |
49 ngx_log_debug(ev->log, "ADDR %s" _ ls->listening->addr_text.data); | |
50 | 61 |
51 s = accept(ls->fd, sa, &len); | 62 s = accept(ls->fd, sa, &len); |
52 if (s == -1) { | 63 if (s == -1) { |
53 err = ngx_socket_errno; | 64 err = ngx_socket_errno; |
54 | 65 |
55 if (err == NGX_EAGAIN) { | 66 if (err == NGX_EAGAIN) { |
56 ngx_log_error(NGX_LOG_NOTICE, ev->log, err, | 67 ngx_log_error(NGX_LOG_NOTICE, log, err, |
57 "EAGAIN while accept() %s", | 68 "EAGAIN after %d accepted connection(s)", |
58 ls->listening->addr_text.data); | 69 accepted); |
59 return; | 70 return; |
60 } | 71 } |
61 | 72 |
62 ngx_log_error(NGX_LOG_ALERT, ev->log, err, | 73 ngx_log_error(NGX_LOG_ALERT, ev->log, err, |
63 "accept() %s failed", ls->listening->addr_text.data); | 74 "accept() on %s failed", |
75 ls->listening->addr_text.data); | |
64 | 76 |
65 ngx_destroy_pool(pool); | 77 ngx_destroy_pool(pool); |
66 return; | 78 return; |
67 } | 79 } |
68 | 80 |
69 /* disable warning: Win32 SOCKET is u_int while UNIX socket is int */ | 81 /* disable warning: Win32 SOCKET is u_int while UNIX socket is int */ |
70 | 82 |
71 if ((unsigned) s >= (unsigned) ecf->connections) { | 83 if ((unsigned) s >= (unsigned) ecf->connections) { |
72 | 84 |
73 ngx_log_error(NGX_LOG_ALERT, ev->log, 0, | 85 ngx_log_error(NGX_LOG_ALERT, ev->log, 0, |
74 "accept() %s returned socket #%d while " | 86 "accept() on %s returned socket #%d while " |
75 "only %d connections was configured, " | 87 "only %d connections was configured, " |
76 "sleeping for 1 second", | 88 "sleeping for 1 second", |
77 ls->listening->addr_text.data, s, ecf->connections); | 89 ls->listening->addr_text.data, s, ecf->connections); |
78 | 90 |
79 if (ngx_close_socket(s) == -1) { | 91 if (ngx_close_socket(s) == -1) { |
80 ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_socket_errno, | 92 ngx_log_error(NGX_LOG_ALERT, log, ngx_socket_errno, |
81 ngx_close_socket_n " %s failed", | 93 ngx_close_socket_n "failed"); |
82 ls->listening->addr_text.data); | |
83 } | 94 } |
84 | 95 |
85 ngx_msleep(1000); | 96 ngx_msleep(1000); |
86 | 97 |
87 ngx_destroy_pool(pool); | 98 ngx_destroy_pool(pool); |
91 /* set a blocking mode for aio and non-blocking mode for others */ | 102 /* set a blocking mode for aio and non-blocking mode for others */ |
92 | 103 |
93 if (ngx_inherited_nonblocking) { | 104 if (ngx_inherited_nonblocking) { |
94 if ((ngx_event_flags & NGX_USE_AIO_EVENT)) { | 105 if ((ngx_event_flags & NGX_USE_AIO_EVENT)) { |
95 if (ngx_blocking(s) == -1) { | 106 if (ngx_blocking(s) == -1) { |
96 ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_socket_errno, | 107 ngx_log_error(NGX_LOG_ALERT, log, ngx_socket_errno, |
97 ngx_blocking_n " %s failed", | 108 ngx_blocking_n " failed"); |
98 ls->listening->addr_text.data); | |
99 | 109 |
100 if (ngx_close_socket(s) == -1) { | 110 if (ngx_close_socket(s) == -1) { |
101 ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_socket_errno, | 111 ngx_log_error(NGX_LOG_ALERT, log, ngx_socket_errno, |
102 ngx_close_socket_n " %s failed", | 112 ngx_close_socket_n " failed"); |
103 ls->listening->addr_text.data); | |
104 } | 113 } |
105 | 114 |
106 ngx_destroy_pool(pool); | 115 ngx_destroy_pool(pool); |
107 return; | 116 return; |
108 } | 117 } |
109 } | 118 } |
110 | 119 |
111 } else { | 120 } else { |
112 if ((ngx_event_flags & NGX_USE_AIO_EVENT) == 0) { | 121 if ((ngx_event_flags & NGX_USE_AIO_EVENT) == 0) { |
113 if (ngx_nonblocking(s) == -1) { | 122 if (ngx_nonblocking(s) == -1) { |
114 ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_socket_errno, | 123 ngx_log_error(NGX_LOG_ALERT, log, ngx_socket_errno, |
115 ngx_nonblocking_n " %s failed", | 124 ngx_nonblocking_n " failed"); |
116 ls->listening->addr_text.data); | |
117 | 125 |
118 if (ngx_close_socket(s) == -1) { | 126 if (ngx_close_socket(s) == -1) { |
119 ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_socket_errno, | 127 ngx_log_error(NGX_LOG_ALERT, log, ngx_socket_errno, |
120 ngx_close_socket_n " %s failed", | 128 ngx_close_socket_n " failed"); |
121 ls->listening->addr_text.data); | |
122 } | 129 } |
123 | 130 |
124 ngx_destroy_pool(pool); | 131 ngx_destroy_pool(pool); |
125 return; | 132 return; |
126 } | 133 } |
132 * Winsock assignes a socket number divisible by 4 | 139 * Winsock assignes a socket number divisible by 4 |
133 * so to find a connection we divide a socket number by 4. | 140 * so to find a connection we divide a socket number by 4. |
134 */ | 141 */ |
135 | 142 |
136 if (s % 4) { | 143 if (s % 4) { |
137 ngx_log_error(NGX_LOG_EMERG, ls->log, 0, | 144 ngx_log_error(NGX_LOG_EMERG, ev->log, 0, |
138 ngx_socket_n | 145 "accept() on %s returned socket #%d, " |
139 " created socket %d, not divisible by 4", s); | 146 "not divisible by 4", |
147 ls->listening->addr_text.data, s); | |
140 exit(1); | 148 exit(1); |
141 } | 149 } |
142 | 150 |
143 c = &ngx_cycle->connections[s / 4]; | 151 c = &ngx_cycle->connections[s / 4]; |
144 rev = &ngx_cycle->read_events[s / 4]; | 152 rev = &ngx_cycle->read_events[s / 4]; |
159 | 167 |
160 c->listening = ls->listening; | 168 c->listening = ls->listening; |
161 c->sockaddr = sa; | 169 c->sockaddr = sa; |
162 c->socklen = len; | 170 c->socklen = len; |
163 | 171 |
164 rev->instance = wev->instance = !instance; | 172 rev->instance = !instance; |
165 | 173 wev->instance = !instance; |
166 rev->index = wev->index = NGX_INVALID_INDEX; | 174 |
167 | 175 rev->index = NGX_INVALID_INDEX; |
168 rev->data = wev->data = c; | 176 wev->index = NGX_INVALID_INDEX; |
177 | |
178 rev->data = c; | |
179 wev->data = c; | |
180 | |
169 c->read = rev; | 181 c->read = rev; |
170 c->write = wev; | 182 c->write = wev; |
171 | 183 |
172 c->fd = s; | 184 c->fd = s; |
173 c->unexpected_eof = 1; | 185 c->unexpected_eof = 1; |
186 | |
174 wev->write = 1; | 187 wev->write = 1; |
175 wev->ready = 1; | 188 wev->ready = 1; |
176 | 189 |
177 if (ngx_event_flags & (NGX_USE_AIO_EVENT|NGX_USE_EDGE_EVENT)) { | 190 if (ngx_event_flags & (NGX_USE_AIO_EVENT|NGX_USE_EDGE_EVENT)) { |
178 /* aio, iocp, epoll */ | 191 /* aio, iocp, epoll */ |
180 } | 193 } |
181 | 194 |
182 c->ctx = ls->ctx; | 195 c->ctx = ls->ctx; |
183 c->servers = ls->servers; | 196 c->servers = ls->servers; |
184 | 197 |
185 c->log = ngx_palloc(c->pool, sizeof(ngx_log_t)); | 198 c->log = log; |
186 if (c->log == NULL) { | 199 rev->log = log; |
187 return; | 200 wev->log = log; |
188 } | |
189 ngx_memcpy(c->log, ls->log, sizeof(ngx_log_t)); | |
190 rev->log = wev->log = c->log; | |
191 | 201 |
192 /* TODO: x86: MT: lock xadd, MP: lock xadd, shared */ | 202 /* TODO: x86: MT: lock xadd, MP: lock xadd, shared */ |
193 c->number = ngx_connection_counter++; | 203 c->number = ngx_connection_counter++; |
194 | 204 |
195 ngx_log_debug(ev->log, "accept: %d, %d" _ s _ c->number); | 205 ngx_log_debug(ev->log, "accept: %d, %d" _ s _ c->number); |
200 | 210 |
201 if (ngx_add_conn) { | 211 if (ngx_add_conn) { |
202 if (ngx_add_conn(c) == NGX_ERROR) { | 212 if (ngx_add_conn(c) == NGX_ERROR) { |
203 if (ngx_close_socket(s) == -1) { | 213 if (ngx_close_socket(s) == -1) { |
204 ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_socket_errno, | 214 ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_socket_errno, |
205 ngx_close_socket_n " %s failed", | 215 ngx_close_socket_n " failed"); |
206 ls->listening->addr_text.data); | |
207 } | 216 } |
208 | 217 |
209 ngx_destroy_pool(pool); | 218 ngx_destroy_pool(pool); |
210 return; | 219 return; |
211 } | 220 } |
212 } | 221 } |
213 | 222 |
223 log->data = NULL; | |
224 log->handler = NULL; | |
225 | |
214 ls->listening->handler(c); | 226 ls->listening->handler(c); |
215 | 227 |
228 #if 0 | |
216 if (ngx_event_flags & NGX_HAVE_KQUEUE_EVENT) { | 229 if (ngx_event_flags & NGX_HAVE_KQUEUE_EVENT) { |
217 ev->available--; | 230 ev->available--; |
218 } | 231 } |
232 #endif | |
233 | |
234 accepted++; | |
219 | 235 |
220 } while (ev->available); | 236 } while (ev->available); |
221 | 237 |
222 return; | 238 return; |
223 } | 239 } |
240 | |
241 | |
242 static size_t ngx_accept_log_error(void *data, char *buf, size_t len) | |
243 { | |
244 char *sock = data; | |
245 | |
246 return ngx_snprintf(buf, len, " while accept() on %s", sock); | |
247 } |