Mercurial > hg > nginx
comparison src/core/ngx_cycle.c @ 218:05592fd7a436
nginx-0.0.1-2004-01-05-23:55:48 import
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Mon, 05 Jan 2004 20:55:48 +0000 |
parents | |
children | f57597ec5249 |
comparison
equal
deleted
inserted
replaced
217:c5d1cdcb04ec | 218:05592fd7a436 |
---|---|
1 | |
2 #include <ngx_config.h> | |
3 #include <ngx_core.h> | |
4 #include <ngx_event.h> | |
5 /* STUB */ | |
6 #include <nginx.h> | |
7 | |
8 | |
9 static void ngx_clean_old_cycles(ngx_event_t *ev); | |
10 | |
11 | |
12 volatile ngx_cycle_t *ngx_cycle; | |
13 ngx_array_t ngx_old_cycles; | |
14 | |
15 static ngx_pool_t *ngx_temp_pool; | |
16 static ngx_event_t ngx_cleaner_event; | |
17 | |
18 | |
19 /* STUB NAME */ | |
20 static ngx_connection_t dumb; | |
21 /* STUB */ | |
22 | |
23 | |
24 ngx_cycle_t *ngx_init_cycle(ngx_cycle_t *old_cycle) | |
25 { | |
26 ngx_int_t i, n, failed; | |
27 ngx_str_t conf_file; | |
28 ngx_log_t *log; | |
29 ngx_conf_t conf; | |
30 ngx_pool_t *pool; | |
31 ngx_cycle_t *cycle, **old; | |
32 ngx_socket_t fd; | |
33 ngx_open_file_t *file; | |
34 ngx_listening_t *ls, *nls; | |
35 | |
36 log = old_cycle->log; | |
37 | |
38 if (!(pool = ngx_create_pool(16 * 1024, log))) { | |
39 return NULL; | |
40 } | |
41 | |
42 if (!(cycle = ngx_pcalloc(pool, sizeof(ngx_cycle_t)))) { | |
43 ngx_destroy_pool(pool); | |
44 return NULL; | |
45 } | |
46 cycle->pool = pool; | |
47 | |
48 cycle->old_cycle = old_cycle; | |
49 | |
50 | |
51 n = old_cycle->pathes.nelts ? old_cycle->pathes.nelts : 10; | |
52 if (!(cycle->pathes.elts = ngx_pcalloc(pool, n * sizeof(ngx_path_t *)))) { | |
53 ngx_destroy_pool(pool); | |
54 return NULL; | |
55 } | |
56 cycle->pathes.nelts = 0; | |
57 cycle->pathes.size = sizeof(ngx_path_t *); | |
58 cycle->pathes.nalloc = n; | |
59 cycle->pathes.pool = pool; | |
60 | |
61 | |
62 n = old_cycle->open_files.nelts ? old_cycle->open_files.nelts : 20; | |
63 cycle->open_files.elts = ngx_pcalloc(pool, n * sizeof(ngx_open_file_t)); | |
64 if (cycle->open_files.elts == NULL) { | |
65 ngx_destroy_pool(pool); | |
66 return NULL; | |
67 } | |
68 cycle->open_files.nelts = 0; | |
69 cycle->open_files.size = sizeof(ngx_open_file_t); | |
70 cycle->open_files.nalloc = n; | |
71 cycle->open_files.pool = pool; | |
72 | |
73 | |
74 if (!(cycle->log = ngx_log_create_errlog(cycle, NULL))) { | |
75 ngx_destroy_pool(pool); | |
76 return NULL; | |
77 } | |
78 | |
79 | |
80 n = old_cycle->listening.nelts ? old_cycle->listening.nelts : 10; | |
81 cycle->listening.elts = ngx_pcalloc(pool, n * sizeof(ngx_listening_t)); | |
82 if (cycle->listening.elts == NULL) { | |
83 ngx_destroy_pool(pool); | |
84 return NULL; | |
85 } | |
86 cycle->listening.nelts = 0; | |
87 cycle->listening.size = sizeof(ngx_listening_t); | |
88 cycle->listening.nalloc = n; | |
89 cycle->listening.pool = pool; | |
90 | |
91 | |
92 cycle->conf_ctx = ngx_pcalloc(pool, ngx_max_module * sizeof(void *)); | |
93 if (cycle->conf_ctx == NULL) { | |
94 ngx_destroy_pool(pool); | |
95 return NULL; | |
96 } | |
97 | |
98 | |
99 if (ngx_core_module.init_module(cycle) == NGX_ERROR) { | |
100 ngx_destroy_pool(pool); | |
101 return NULL; | |
102 } | |
103 | |
104 | |
105 ngx_memzero(&conf, sizeof(ngx_conf_t)); | |
106 /* STUB: init array ? */ | |
107 conf.args = ngx_create_array(pool, 10, sizeof(ngx_str_t)); | |
108 if (conf.args == NULL) { | |
109 ngx_destroy_pool(pool); | |
110 return NULL; | |
111 } | |
112 | |
113 conf.ctx = cycle->conf_ctx; | |
114 conf.cycle = cycle; | |
115 /* STUB */ conf.pool = cycle->pool; | |
116 conf.log = log; | |
117 conf.module_type = NGX_CORE_MODULE; | |
118 conf.cmd_type = NGX_MAIN_CONF; | |
119 | |
120 conf_file.len = sizeof(NGINX_CONF) - 1; | |
121 conf_file.data = NGINX_CONF; | |
122 | |
123 if (ngx_conf_parse(&conf, &conf_file) != NGX_CONF_OK) { | |
124 ngx_destroy_pool(pool); | |
125 return NULL; | |
126 } | |
127 | |
128 | |
129 failed = 0; | |
130 | |
131 file = cycle->open_files.elts; | |
132 for (i = 0; i < cycle->open_files.nelts; i++) { | |
133 if (file[i].name.data == NULL) { | |
134 continue; | |
135 } | |
136 | |
137 file[i].fd = ngx_open_file(file[i].name.data, | |
138 NGX_FILE_RDWR, | |
139 NGX_FILE_CREATE_OR_OPEN|NGX_FILE_APPEND); | |
140 | |
141 ngx_log_debug(log, "OPEN: %d:%s" _ file[i].fd _ file[i].name.data); | |
142 | |
143 if (file[i].fd == NGX_INVALID_FILE) { | |
144 ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, | |
145 ngx_open_file_n " \"%s\" failed", | |
146 file[i].name.data); | |
147 failed = 1; | |
148 break; | |
149 } | |
150 | |
151 #if (WIN32) | |
152 if (ngx_file_append_mode(file[i].fd) == NGX_ERROR) { | |
153 ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, | |
154 ngx_file_append_mode_n " \"%s\" failed", | |
155 file[i].name.data); | |
156 failed = 1; | |
157 break; | |
158 } | |
159 #endif | |
160 } | |
161 | |
162 if (!failed) { | |
163 if (old_cycle->listening.nelts) { | |
164 ls = old_cycle->listening.elts; | |
165 for (i = 0; i < old_cycle->listening.nelts; i++) { | |
166 ls[i].remain = 0; | |
167 } | |
168 | |
169 nls = cycle->listening.elts; | |
170 for (n = 0; n < cycle->listening.nelts; n++) { | |
171 for (i = 0; i < old_cycle->listening.nelts; i++) { | |
172 if (ls[i].ignore) { | |
173 continue; | |
174 } | |
175 | |
176 ngx_log_error(NGX_LOG_INFO, log, 0, | |
177 "%X, %X", | |
178 *(int *) ls[i].sockaddr, | |
179 *(int *) nls[n].sockaddr); | |
180 | |
181 if (ngx_memcmp(nls[n].sockaddr, | |
182 ls[i].sockaddr, ls[i].socklen) == 0) | |
183 { | |
184 fd = ls[i].fd; | |
185 #if (WIN32) | |
186 /* | |
187 * Winsock assignes a socket number divisible by 4 so | |
188 * to find a connection we divide a socket number by 4. | |
189 */ | |
190 | |
191 fd /= 4; | |
192 #endif | |
193 if (fd >= (ngx_socket_t) cycle->connection_n) { | |
194 ngx_log_error(NGX_LOG_EMERG, log, 0, | |
195 "%d connections is not enough to hold " | |
196 "an open listening socket on %s, " | |
197 "required at least %d connections", | |
198 cycle->connection_n, | |
199 ls[i].addr_text.data, fd); | |
200 failed = 1; | |
201 break; | |
202 } | |
203 | |
204 nls[n].fd = ls[i].fd; | |
205 nls[i].remain = 1; | |
206 ls[i].remain = 1; | |
207 break; | |
208 } | |
209 } | |
210 | |
211 if (nls[n].fd == -1) { | |
212 nls[n].new = 1; | |
213 } | |
214 } | |
215 | |
216 } else { | |
217 ls = cycle->listening.elts; | |
218 for (i = 0; i < cycle->listening.nelts; i++) { | |
219 ls[i].new = 1; | |
220 } | |
221 } | |
222 | |
223 if (!failed) { | |
224 if (ngx_open_listening_sockets(cycle) == NGX_ERROR) { | |
225 failed = 1; | |
226 } | |
227 } | |
228 } | |
229 | |
230 if (failed) { | |
231 | |
232 /* rollback the new cycle configuration */ | |
233 | |
234 file = cycle->open_files.elts; | |
235 for (i = 0; i < cycle->open_files.nelts; i++) { | |
236 if (file[i].fd == NGX_INVALID_FILE) { | |
237 continue; | |
238 } | |
239 | |
240 if (ngx_close_file(file[i].fd) == NGX_FILE_ERROR) { | |
241 ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, | |
242 ngx_close_file_n " \"%s\" failed", | |
243 file[i].name.data); | |
244 } | |
245 } | |
246 | |
247 ls = cycle->listening.elts; | |
248 for (i = 0; i < cycle->listening.nelts; i++) { | |
249 if (ls[i].new && ls[i].fd == -1) { | |
250 continue; | |
251 } | |
252 | |
253 if (ngx_close_socket(ls[i].fd) == -1) { | |
254 ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno, | |
255 ngx_close_socket_n " %s failed", | |
256 ls[i].addr_text.data); | |
257 } | |
258 } | |
259 | |
260 ngx_destroy_pool(pool); | |
261 return NULL; | |
262 } | |
263 | |
264 /* commit the new cycle configuration */ | |
265 | |
266 pool->log = cycle->log; | |
267 | |
268 | |
269 for (i = 0; ngx_modules[i]; i++) { | |
270 if (ngx_modules[i]->init_module) { | |
271 if (ngx_modules[i]->init_module(cycle) == NGX_ERROR) { | |
272 /* fatal */ | |
273 exit(1); | |
274 } | |
275 } | |
276 } | |
277 | |
278 /* close and delete stuff that lefts from an old cycle */ | |
279 | |
280 /* close the unneeded listening sockets */ | |
281 | |
282 ls = old_cycle->listening.elts; | |
283 for (i = 0; i < old_cycle->listening.nelts; i++) { | |
284 if (ls[i].remain) { | |
285 continue; | |
286 } | |
287 | |
288 if (ngx_close_socket(ls[i].fd) == -1) { | |
289 ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno, | |
290 ngx_close_socket_n " %s failed", | |
291 ls[i].addr_text.data); | |
292 } | |
293 } | |
294 | |
295 | |
296 /* close the unneeded open files */ | |
297 | |
298 file = old_cycle->open_files.elts; | |
299 for (i = 0; i < old_cycle->open_files.nelts; i++) { | |
300 if (file[i].fd == NGX_INVALID_FILE) { | |
301 continue; | |
302 } | |
303 | |
304 if (ngx_close_file(file[i].fd) == NGX_FILE_ERROR) { | |
305 ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, | |
306 ngx_close_file_n " \"%s\" failed", | |
307 file[i].name.data); | |
308 } | |
309 } | |
310 | |
311 if (old_cycle->connections == NULL) { | |
312 /* an old cycle is an init cycle */ | |
313 ngx_destroy_pool(old_cycle->pool); | |
314 return cycle; | |
315 } | |
316 | |
317 if (ngx_master) { | |
318 ngx_destroy_pool(old_cycle->pool); | |
319 return cycle; | |
320 } | |
321 | |
322 if (ngx_temp_pool == NULL) { | |
323 ngx_temp_pool = ngx_create_pool(128, cycle->log); | |
324 if (ngx_temp_pool == NULL) { | |
325 ngx_log_error(NGX_LOG_EMERG, cycle->log, 0, | |
326 "can not create ngx_temp_pool"); | |
327 exit(1); | |
328 } | |
329 | |
330 n = 10; | |
331 ngx_old_cycles.elts = ngx_pcalloc(ngx_temp_pool, | |
332 n * sizeof(ngx_cycle_t *)); | |
333 if (ngx_old_cycles.elts == NULL) { | |
334 exit(1); | |
335 } | |
336 ngx_old_cycles.nelts = 0; | |
337 ngx_old_cycles.size = sizeof(ngx_cycle_t *); | |
338 ngx_old_cycles.nalloc = n; | |
339 ngx_old_cycles.pool = ngx_temp_pool; | |
340 | |
341 ngx_cleaner_event.event_handler = ngx_clean_old_cycles; | |
342 ngx_cleaner_event.log = cycle->log; | |
343 ngx_cleaner_event.data = &dumb; | |
344 dumb.fd = (ngx_socket_t) -1; | |
345 } | |
346 | |
347 ngx_temp_pool->log = cycle->log; | |
348 | |
349 old = ngx_push_array(&ngx_old_cycles); | |
350 if (old == NULL) { | |
351 exit(1); | |
352 } | |
353 *old = old_cycle; | |
354 | |
355 if (!ngx_cleaner_event.timer_set) { | |
356 ngx_add_timer(&ngx_cleaner_event, 30000); | |
357 ngx_cleaner_event.timer_set = 1; | |
358 } | |
359 | |
360 return cycle; | |
361 } | |
362 | |
363 | |
364 #if 0 | |
365 | |
366 | |
367 static ngx_int_t ngx_set_inherited_sockets(ngx_cycle_t *cycle, char **envp) | |
368 { | |
369 char *p, *v; | |
370 ngx_socket_t s; | |
371 ngx_listening_t *ls; | |
372 struct sockaddr_in *addr_in; | |
373 | |
374 for ( /* void */ ; *envp; envp++) { | |
375 if (ngx_strncmp(*envp, NGINX_VAR, NGINX_VAR_LEN) != 0) { | |
376 continue; | |
377 } | |
378 | |
379 ngx_log_error(NGX_LOG_INFO, cycle->log, 0, | |
380 "using inherited sockets from \"%s\"", *envp); | |
381 | |
382 ngx_init_array(cycle->listening, cycle->pool, | |
383 10, sizeof(ngx_listening_t), NGX_ERROR); | |
384 | |
385 for (p = *envp + NGINX_VAR_LEN, v = p; *p; p++) { | |
386 if (*p == ':' || *p == ';') { | |
387 s = ngx_atoi(v, p - v); | |
388 if (s == NGX_ERROR) { | |
389 ngx_log_error(NGX_LOG_EMERG, cycle->log, 0, | |
390 "invalid socket number \"%s\" " | |
391 "in NGINX enviroment variable, " | |
392 "ignoring the rest of the variable", v); | |
393 break; | |
394 } | |
395 v = p + 1; | |
396 | |
397 if (!(ls = ngx_push_array(&cycle->listening))) { | |
398 return NGX_ERROR; | |
399 } | |
400 | |
401 ls->fd = s; | |
402 | |
403 /* AF_INET only */ | |
404 | |
405 ls->sockaddr = ngx_palloc(cycle->pool, | |
406 sizeof(struct sockaddr_in)); | |
407 if (ls->sockaddr == NULL) { | |
408 return NGX_ERROR; | |
409 } | |
410 | |
411 ls->socklen = sizeof(struct sockaddr_in); | |
412 if (getsockname(s, ls->sockaddr, &ls->socklen) == -1) { | |
413 ngx_log_error(NGX_LOG_CRIT, cycle->log, ngx_socket_errno, | |
414 "getsockname() of the inherited " | |
415 "socket #%d failed", s); | |
416 ls->ignore = 1; | |
417 continue; | |
418 } | |
419 | |
420 addr_in = (struct sockaddr_in *) ls->sockaddr; | |
421 | |
422 if (addr_in->sin_family != AF_INET) { | |
423 ngx_log_error(NGX_LOG_CRIT, cycle->log, ngx_socket_errno, | |
424 "the inherited socket #%d has " | |
425 "unsupported family", s); | |
426 ls->ignore = 1; | |
427 continue; | |
428 } | |
429 ls->addr_text_max_len = INET_ADDRSTRLEN; | |
430 | |
431 ls->addr_text.data = ngx_palloc(cycle->pool, | |
432 ls->addr_text_max_len); | |
433 if (ls->addr_text.data == NULL) { | |
434 return NGX_ERROR; | |
435 } | |
436 | |
437 addr_in->sin_len = 0; | |
438 | |
439 ls->family = addr_in->sin_family; | |
440 ls->addr_text.len = ngx_sock_ntop(ls->family, ls->sockaddr, | |
441 ls->addr_text.data, | |
442 ls->addr_text_max_len); | |
443 if (ls->addr_text.len == 0) { | |
444 return NGX_ERROR; | |
445 } | |
446 } | |
447 } | |
448 | |
449 break; | |
450 } | |
451 | |
452 return NGX_OK; | |
453 } | |
454 | |
455 | |
456 static ngx_int_t ngx_open_listening_sockets(ngx_cycle_t *cycle) | |
457 { | |
458 int tries, failed, reuseaddr, i; | |
459 ngx_err_t err; | |
460 ngx_log_t *log; | |
461 ngx_socket_t s; | |
462 ngx_listening_t *ls; | |
463 | |
464 reuseaddr = 1; | |
465 #if (NGX_SUPPRESS_WARN) | |
466 failed = 0; | |
467 #endif | |
468 | |
469 log = cycle->log; | |
470 | |
471 /* TODO: tries configurable */ | |
472 | |
473 for (tries = 10; tries; tries--) { | |
474 failed = 0; | |
475 | |
476 /* for each listening socket */ | |
477 | |
478 ls = cycle->listening.elts; | |
479 for (i = 0; i < cycle->listening.nelts; i++) { | |
480 | |
481 if (ls[i].ignore) { | |
482 continue; | |
483 } | |
484 | |
485 if (ls[i].fd != -1) { | |
486 continue; | |
487 } | |
488 | |
489 if (ls[i].inherited) { | |
490 | |
491 /* TODO: close on exit */ | |
492 /* TODO: nonblocking */ | |
493 /* TODO: deferred accept */ | |
494 | |
495 continue; | |
496 } | |
497 | |
498 s = ngx_socket(ls[i].family, ls[i].type, ls[i].protocol, | |
499 ls[i].flags); | |
500 | |
501 if (s == -1) { | |
502 ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno, | |
503 ngx_socket_n " %s failed", ls[i].addr_text.data); | |
504 return NGX_ERROR; | |
505 } | |
506 | |
507 #if (WIN32) | |
508 /* | |
509 * Winsock assignes a socket number divisible by 4 | |
510 * so to find a connection we divide a socket number by 4. | |
511 */ | |
512 | |
513 if (s % 4) { | |
514 ngx_log_error(NGX_LOG_EMERG, ls->log, 0, | |
515 ngx_socket_n " created socket %d", s); | |
516 return NGX_ERROR; | |
517 } | |
518 #endif | |
519 | |
520 if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, | |
521 (const void *) &reuseaddr, sizeof(int)) == -1) { | |
522 ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno, | |
523 "setsockopt(SO_REUSEADDR) %s failed", | |
524 ls[i].addr_text.data); | |
525 return NGX_ERROR; | |
526 } | |
527 | |
528 /* TODO: close on exit */ | |
529 | |
530 if (!(ngx_event_flags & NGX_USE_AIO_EVENT)) { | |
531 if (ngx_nonblocking(s) == -1) { | |
532 ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno, | |
533 ngx_nonblocking_n " %s failed", | |
534 ls[i].addr_text.data); | |
535 return NGX_ERROR; | |
536 } | |
537 } | |
538 | |
539 #if 0 | |
540 if (ls[i].nonblocking) { | |
541 if (ngx_nonblocking(s) == -1) { | |
542 ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno, | |
543 ngx_nonblocking_n " %s failed", | |
544 ls[i].addr_text.data); | |
545 return NGX_ERROR; | |
546 } | |
547 } | |
548 #endif | |
549 | |
550 if (bind(s, ls[i].sockaddr, ls[i].socklen) == -1) { | |
551 err = ngx_socket_errno; | |
552 ngx_log_error(NGX_LOG_EMERG, log, err, | |
553 "bind() to %s failed", ls[i].addr_text.data); | |
554 | |
555 if (err != NGX_EADDRINUSE) | |
556 return NGX_ERROR; | |
557 | |
558 if (ngx_close_socket(s) == -1) | |
559 ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno, | |
560 ngx_close_socket_n " %s failed", | |
561 ls[i].addr_text.data); | |
562 | |
563 failed = 1; | |
564 continue; | |
565 } | |
566 | |
567 if (listen(s, ls[i].backlog) == -1) { | |
568 ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno, | |
569 "listen() to %s failed", ls[i].addr_text.data); | |
570 return NGX_ERROR; | |
571 } | |
572 | |
573 /* TODO: deferred accept */ | |
574 | |
575 ls[i].fd = s; | |
576 } | |
577 | |
578 if (!failed) | |
579 break; | |
580 | |
581 /* TODO: delay configurable */ | |
582 | |
583 ngx_log_error(NGX_LOG_NOTICE, log, 0, | |
584 "try again to bind() after 500ms"); | |
585 ngx_msleep(500); | |
586 } | |
587 | |
588 if (failed) { | |
589 ngx_log_error(NGX_LOG_EMERG, log, 0, "still can not bind()"); | |
590 return NGX_ERROR; | |
591 } | |
592 | |
593 return NGX_OK; | |
594 } | |
595 | |
596 | |
597 #endif | |
598 | |
599 | |
600 void ngx_reopen_files(ngx_cycle_t *cycle) | |
601 { | |
602 ngx_fd_t fd; | |
603 ngx_int_t i; | |
604 ngx_open_file_t *file; | |
605 | |
606 file = cycle->open_files.elts; | |
607 for (i = 0; i < cycle->open_files.nelts; i++) { | |
608 if (file[i].name.data == NULL) { | |
609 continue; | |
610 } | |
611 | |
612 fd = ngx_open_file(file[i].name.data, NGX_FILE_RDWR, | |
613 NGX_FILE_CREATE_OR_OPEN|NGX_FILE_APPEND); | |
614 | |
615 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, cycle->log, 0, | |
616 "reopen file \"%s\", old:%d new:%d", | |
617 file[i].name.data, file[i].fd, fd); | |
618 | |
619 if (fd == NGX_INVALID_FILE) { | |
620 ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, | |
621 ngx_open_file_n " \"%s\" failed", file[i].name.data); | |
622 continue; | |
623 } | |
624 | |
625 #if (WIN32) | |
626 if (ngx_file_append_mode(fd) == NGX_ERROR) { | |
627 ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, | |
628 ngx_file_append_mode_n " \"%s\" failed", | |
629 file[i].name.data); | |
630 | |
631 if (ngx_close_file(fd) == NGX_FILE_ERROR) { | |
632 ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, | |
633 ngx_close_file_n " \"%s\" failed", | |
634 file[i].name.data); | |
635 } | |
636 | |
637 continue; | |
638 } | |
639 #endif | |
640 | |
641 if (ngx_close_file(file[i].fd) == NGX_FILE_ERROR) { | |
642 ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, | |
643 ngx_close_file_n " \"%s\" failed", | |
644 file[i].name.data); | |
645 } | |
646 | |
647 file[i].fd = fd; | |
648 } | |
649 } | |
650 | |
651 | |
652 #if 0 | |
653 | |
654 static void ngx_close_listening_sockets(ngx_cycle_t *cycle) | |
655 { | |
656 ngx_int_t i; | |
657 ngx_socket_t fd; | |
658 ngx_listening_t *ls; | |
659 | |
660 if (ngx_event_flags & NGX_USE_IOCP_EVENT) { | |
661 return; | |
662 } | |
663 | |
664 ls = cycle->listening.elts; | |
665 for (i = 0; i < cycle->listening.nelts; i++) { | |
666 fd = ls[i].fd; | |
667 | |
668 #if (WIN32) | |
669 /* | |
670 * Winsock assignes a socket number divisible by 4 | |
671 * so to find a connection we divide a socket number by 4. | |
672 */ | |
673 | |
674 fd /= 4; | |
675 #endif | |
676 | |
677 ngx_del_event(&cycle->read_events[fd], NGX_READ_EVENT, NGX_CLOSE_EVENT); | |
678 | |
679 if (ngx_close_socket(ls[i].fd) == -1) { | |
680 ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_socket_errno, | |
681 ngx_close_socket_n " %s failed", | |
682 ls[i].addr_text.data); | |
683 } | |
684 | |
685 cycle->connections[fd].fd = -1; | |
686 } | |
687 } | |
688 | |
689 #endif | |
690 | |
691 | |
692 static void ngx_clean_old_cycles(ngx_event_t *ev) | |
693 { | |
694 int i, n, found, live; | |
695 ngx_log_t *log; | |
696 ngx_cycle_t **cycle; | |
697 | |
698 log = ngx_cycle->log; | |
699 ngx_temp_pool->log = log; | |
700 | |
701 ngx_log_debug(log, "clean old cycles"); | |
702 | |
703 live = 0; | |
704 | |
705 cycle = ngx_old_cycles.elts; | |
706 for (i = 0; i < ngx_old_cycles.nelts; i++) { | |
707 | |
708 if (cycle[i] == NULL) { | |
709 continue; | |
710 } | |
711 | |
712 found = 0; | |
713 | |
714 for (n = 0; n < cycle[i]->connection_n; n++) { | |
715 if (cycle[i]->connections[n].fd != -1) { | |
716 found = 1; | |
717 ngx_log_debug(log, "live fd: %d" _ n); | |
718 break; | |
719 } | |
720 } | |
721 | |
722 if (found) { | |
723 live = 1; | |
724 continue; | |
725 } | |
726 | |
727 ngx_log_debug(log, "clean old cycle: %d" _ i); | |
728 ngx_destroy_pool(cycle[i]->pool); | |
729 cycle[i] = NULL; | |
730 } | |
731 | |
732 ngx_log_debug(log, "old cycles status: %d" _ live); | |
733 | |
734 if (live) { | |
735 ngx_log_debug(log, "TIMER"); | |
736 ngx_add_timer(ev, 30000); | |
737 | |
738 } else { | |
739 ngx_destroy_pool(ngx_temp_pool); | |
740 ngx_temp_pool = NULL; | |
741 ngx_old_cycles.nelts = 0; | |
742 } | |
743 } |