3 * Copyright (C) Igor Sysoev
7 #include <ngx_config.h>
10 #include <ngx_channel.h>
13 static void ngx_start_worker_processes(ngx_cycle_t
*cycle
, ngx_int_t n
,
15 static void ngx_start_cache_manager_processes(ngx_cycle_t
*cycle
,
17 static void ngx_pass_open_channel(ngx_cycle_t
*cycle
, ngx_channel_t
*ch
);
18 static void ngx_signal_worker_processes(ngx_cycle_t
*cycle
, int signo
);
19 static ngx_uint_t
ngx_reap_children(ngx_cycle_t
*cycle
);
20 static void ngx_master_process_exit(ngx_cycle_t
*cycle
);
21 static void ngx_worker_process_cycle(ngx_cycle_t
*cycle
, void *data
);
22 static void ngx_worker_process_init(ngx_cycle_t
*cycle
, ngx_uint_t priority
);
23 static void ngx_worker_process_exit(ngx_cycle_t
*cycle
);
24 static void ngx_channel_handler(ngx_event_t
*ev
);
26 static void ngx_wakeup_worker_threads(ngx_cycle_t
*cycle
);
27 static ngx_thread_value_t
ngx_worker_thread_cycle(void *data
);
29 static void ngx_cache_manager_process_cycle(ngx_cycle_t
*cycle
, void *data
);
30 static void ngx_cache_manager_process_handler(ngx_event_t
*ev
);
31 static void ngx_cache_loader_process_handler(ngx_event_t
*ev
);
34 ngx_uint_t ngx_process
;
36 ngx_uint_t ngx_threaded
;
38 sig_atomic_t ngx_reap
;
39 sig_atomic_t ngx_sigio
;
40 sig_atomic_t ngx_terminate
;
41 sig_atomic_t ngx_quit
;
42 sig_atomic_t ngx_debug_quit
;
43 ngx_uint_t ngx_exiting
;
44 sig_atomic_t ngx_reconfigure
;
45 sig_atomic_t ngx_reopen
;
47 sig_atomic_t ngx_change_binary
;
48 ngx_pid_t ngx_new_binary
;
49 ngx_uint_t ngx_inherited
;
50 ngx_uint_t ngx_daemonized
;
52 sig_atomic_t ngx_noaccept
;
53 ngx_uint_t ngx_noaccepting
;
54 ngx_uint_t ngx_restart
;
58 volatile ngx_thread_t ngx_threads
[NGX_MAX_THREADS
];
59 ngx_int_t ngx_threads_n
;
64 static u_char master_process
[] = "master process";
67 static ngx_cache_manager_ctx_t ngx_cache_manager_ctx
= {
68 ngx_cache_manager_process_handler
, "cache manager process", 0
71 static ngx_cache_manager_ctx_t ngx_cache_loader_ctx
= {
72 ngx_cache_loader_process_handler
, "cache loader process", 60000
76 static ngx_cycle_t ngx_exit_cycle
;
77 static ngx_log_t ngx_exit_log
;
78 static ngx_open_file_t ngx_exit_log_file
;
82 ngx_master_process_cycle(ngx_cycle_t
*cycle
)
97 sigaddset(&set
, SIGCHLD
);
98 sigaddset(&set
, SIGALRM
);
99 sigaddset(&set
, SIGIO
);
100 sigaddset(&set
, SIGINT
);
101 sigaddset(&set
, ngx_signal_value(NGX_RECONFIGURE_SIGNAL
));
102 sigaddset(&set
, ngx_signal_value(NGX_REOPEN_SIGNAL
));
103 sigaddset(&set
, ngx_signal_value(NGX_NOACCEPT_SIGNAL
));
104 sigaddset(&set
, ngx_signal_value(NGX_TERMINATE_SIGNAL
));
105 sigaddset(&set
, ngx_signal_value(NGX_SHUTDOWN_SIGNAL
));
106 sigaddset(&set
, ngx_signal_value(NGX_CHANGEBIN_SIGNAL
));
108 if (sigprocmask(SIG_BLOCK
, &set
, NULL
) == -1) {
109 ngx_log_error(NGX_LOG_ALERT
, cycle
->log
, ngx_errno
,
110 "sigprocmask() failed");
116 size
= sizeof(master_process
);
118 for (i
= 0; i
< ngx_argc
; i
++) {
119 size
+= ngx_strlen(ngx_argv
[i
]) + 1;
122 title
= ngx_pnalloc(cycle
->pool
, size
);
124 p
= ngx_cpymem(title
, master_process
, sizeof(master_process
) - 1);
125 for (i
= 0; i
< ngx_argc
; i
++) {
127 p
= ngx_cpystrn(p
, (u_char
*) ngx_argv
[i
], size
);
130 ngx_setproctitle(title
);
133 ccf
= (ngx_core_conf_t
*) ngx_get_conf(cycle
->conf_ctx
, ngx_core_module
);
135 ngx_start_worker_processes(cycle
, ccf
->worker_processes
,
136 NGX_PROCESS_RESPAWN
);
137 ngx_start_cache_manager_processes(cycle
, 0);
147 ngx_log_debug1(NGX_LOG_DEBUG_EVENT
, cycle
->log
, 0,
148 "temination cycle: %d", delay
);
150 itv
.it_interval
.tv_sec
= 0;
151 itv
.it_interval
.tv_usec
= 0;
152 itv
.it_value
.tv_sec
= delay
/ 1000;
153 itv
.it_value
.tv_usec
= (delay
% 1000 ) * 1000;
155 if (setitimer(ITIMER_REAL
, &itv
, NULL
) == -1) {
156 ngx_log_error(NGX_LOG_ALERT
, cycle
->log
, ngx_errno
,
157 "setitimer() failed");
161 ngx_log_debug0(NGX_LOG_DEBUG_EVENT
, cycle
->log
, 0, "sigsuspend");
165 ngx_time_update(0, 0);
167 ngx_log_debug0(NGX_LOG_DEBUG_EVENT
, cycle
->log
, 0, "wake up");
171 ngx_log_debug0(NGX_LOG_DEBUG_EVENT
, cycle
->log
, 0, "reap children");
173 live
= ngx_reap_children(cycle
);
176 if (!live
&& (ngx_terminate
|| ngx_quit
)) {
177 ngx_master_process_exit(cycle
);
186 ngx_signal_worker_processes(cycle
, SIGKILL
);
188 ngx_signal_worker_processes(cycle
,
189 ngx_signal_value(NGX_TERMINATE_SIGNAL
));
196 ngx_signal_worker_processes(cycle
,
197 ngx_signal_value(NGX_SHUTDOWN_SIGNAL
));
199 ls
= cycle
->listening
.elts
;
200 for (n
= 0; n
< cycle
->listening
.nelts
; n
++) {
201 if (ngx_close_socket(ls
[n
].fd
) == -1) {
202 ngx_log_error(NGX_LOG_EMERG
, cycle
->log
, ngx_socket_errno
,
203 ngx_close_socket_n
" %V failed",
207 cycle
->listening
.nelts
= 0;
212 if (ngx_reconfigure
) {
215 if (ngx_new_binary
) {
216 ngx_start_worker_processes(cycle
, ccf
->worker_processes
,
217 NGX_PROCESS_RESPAWN
);
218 ngx_start_cache_manager_processes(cycle
, 0);
224 ngx_log_error(NGX_LOG_NOTICE
, cycle
->log
, 0, "reconfiguring");
226 cycle
= ngx_init_cycle(cycle
);
228 cycle
= (ngx_cycle_t
*) ngx_cycle
;
233 ccf
= (ngx_core_conf_t
*) ngx_get_conf(cycle
->conf_ctx
,
235 ngx_start_worker_processes(cycle
, ccf
->worker_processes
,
236 NGX_PROCESS_JUST_RESPAWN
);
237 ngx_start_cache_manager_processes(cycle
, 1);
239 ngx_signal_worker_processes(cycle
,
240 ngx_signal_value(NGX_SHUTDOWN_SIGNAL
));
245 ngx_start_worker_processes(cycle
, ccf
->worker_processes
,
246 NGX_PROCESS_RESPAWN
);
247 ngx_start_cache_manager_processes(cycle
, 0);
253 ngx_log_error(NGX_LOG_NOTICE
, cycle
->log
, 0, "reopening logs");
254 ngx_reopen_files(cycle
, ccf
->user
);
255 ngx_signal_worker_processes(cycle
,
256 ngx_signal_value(NGX_REOPEN_SIGNAL
));
259 if (ngx_change_binary
) {
260 ngx_change_binary
= 0;
261 ngx_log_error(NGX_LOG_NOTICE
, cycle
->log
, 0, "changing binary");
262 ngx_new_binary
= ngx_exec_new_binary(cycle
, ngx_argv
);
268 ngx_signal_worker_processes(cycle
,
269 ngx_signal_value(NGX_SHUTDOWN_SIGNAL
));
276 ngx_single_process_cycle(ngx_cycle_t
*cycle
)
280 for (i
= 0; ngx_modules
[i
]; i
++) {
281 if (ngx_modules
[i
]->init_process
) {
282 if (ngx_modules
[i
]->init_process(cycle
) == NGX_ERROR
) {
290 ngx_log_debug0(NGX_LOG_DEBUG_EVENT
, cycle
->log
, 0, "worker cycle");
292 ngx_process_events_and_timers(cycle
);
294 if (ngx_terminate
|| ngx_quit
) {
296 for (i
= 0; ngx_modules
[i
]; i
++) {
297 if (ngx_modules
[i
]->exit_process
) {
298 ngx_modules
[i
]->exit_process(cycle
);
302 ngx_master_process_exit(cycle
);
305 if (ngx_reconfigure
) {
307 ngx_log_error(NGX_LOG_NOTICE
, cycle
->log
, 0, "reconfiguring");
309 cycle
= ngx_init_cycle(cycle
);
311 cycle
= (ngx_cycle_t
*) ngx_cycle
;
320 ngx_log_error(NGX_LOG_NOTICE
, cycle
->log
, 0, "reopening logs");
321 ngx_reopen_files(cycle
, (ngx_uid_t
) -1);
328 ngx_start_worker_processes(ngx_cycle_t
*cycle
, ngx_int_t n
, ngx_int_t type
)
333 ngx_log_error(NGX_LOG_NOTICE
, cycle
->log
, 0, "start worker processes");
335 ch
.command
= NGX_CMD_OPEN_CHANNEL
;
337 for (i
= 0; i
< n
; i
++) {
339 cpu_affinity
= ngx_get_cpu_affinity(i
);
341 ngx_spawn_process(cycle
, ngx_worker_process_cycle
, NULL
,
342 "worker process", type
);
344 ch
.pid
= ngx_processes
[ngx_process_slot
].pid
;
345 ch
.slot
= ngx_process_slot
;
346 ch
.fd
= ngx_processes
[ngx_process_slot
].channel
[0];
348 ngx_pass_open_channel(cycle
, &ch
);
354 ngx_start_cache_manager_processes(ngx_cycle_t
*cycle
, ngx_uint_t respawn
)
356 ngx_uint_t i
, manager
, loader
;
363 path
= ngx_cycle
->pathes
.elts
;
364 for (i
= 0; i
< ngx_cycle
->pathes
.nelts
; i
++) {
366 if (path
[i
]->manager
) {
370 if (path
[i
]->loader
) {
379 ngx_spawn_process(cycle
, ngx_cache_manager_process_cycle
,
380 &ngx_cache_manager_ctx
, "cache manager process",
381 respawn
? NGX_PROCESS_JUST_RESPAWN
: NGX_PROCESS_RESPAWN
);
383 ch
.command
= NGX_CMD_OPEN_CHANNEL
;
384 ch
.pid
= ngx_processes
[ngx_process_slot
].pid
;
385 ch
.slot
= ngx_process_slot
;
386 ch
.fd
= ngx_processes
[ngx_process_slot
].channel
[0];
388 ngx_pass_open_channel(cycle
, &ch
);
394 ngx_spawn_process(cycle
, ngx_cache_manager_process_cycle
,
395 &ngx_cache_loader_ctx
, "cache loader process",
396 respawn
? NGX_PROCESS_JUST_SPAWN
: NGX_PROCESS_NORESPAWN
);
398 ch
.command
= NGX_CMD_OPEN_CHANNEL
;
399 ch
.pid
= ngx_processes
[ngx_process_slot
].pid
;
400 ch
.slot
= ngx_process_slot
;
401 ch
.fd
= ngx_processes
[ngx_process_slot
].channel
[0];
403 ngx_pass_open_channel(cycle
, &ch
);
408 ngx_pass_open_channel(ngx_cycle_t
*cycle
, ngx_channel_t
*ch
)
412 for (i
= 0; i
< ngx_last_process
; i
++) {
414 if (i
== ngx_process_slot
415 || ngx_processes
[i
].pid
== -1
416 || ngx_processes
[i
].channel
[0] == -1)
421 ngx_log_debug6(NGX_LOG_DEBUG_CORE
, cycle
->log
, 0,
422 "pass channel s:%d pid:%P fd:%d to s:%i pid:%P fd:%d",
423 ch
->slot
, ch
->pid
, ch
->fd
,
424 i
, ngx_processes
[i
].pid
,
425 ngx_processes
[i
].channel
[0]);
427 /* TODO: NGX_AGAIN */
429 ngx_write_channel(ngx_processes
[i
].channel
[0],
430 ch
, sizeof(ngx_channel_t
), cycle
->log
);
436 ngx_signal_worker_processes(ngx_cycle_t
*cycle
, int signo
)
442 #if (NGX_BROKEN_SCM_RIGHTS)
450 case ngx_signal_value(NGX_SHUTDOWN_SIGNAL
):
451 ch
.command
= NGX_CMD_QUIT
;
454 case ngx_signal_value(NGX_TERMINATE_SIGNAL
):
455 ch
.command
= NGX_CMD_TERMINATE
;
458 case ngx_signal_value(NGX_REOPEN_SIGNAL
):
459 ch
.command
= NGX_CMD_REOPEN
;
471 for (i
= 0; i
< ngx_last_process
; i
++) {
473 ngx_log_debug7(NGX_LOG_DEBUG_EVENT
, cycle
->log
, 0,
474 "child: %d %P e:%d t:%d d:%d r:%d j:%d",
476 ngx_processes
[i
].pid
,
477 ngx_processes
[i
].exiting
,
478 ngx_processes
[i
].exited
,
479 ngx_processes
[i
].detached
,
480 ngx_processes
[i
].respawn
,
481 ngx_processes
[i
].just_spawn
);
483 if (ngx_processes
[i
].detached
|| ngx_processes
[i
].pid
== -1) {
487 if (ngx_processes
[i
].just_spawn
) {
488 ngx_processes
[i
].just_spawn
= 0;
492 if (ngx_processes
[i
].exiting
493 && signo
== ngx_signal_value(NGX_SHUTDOWN_SIGNAL
))
499 if (ngx_write_channel(ngx_processes
[i
].channel
[0],
500 &ch
, sizeof(ngx_channel_t
), cycle
->log
)
503 if (signo
!= ngx_signal_value(NGX_REOPEN_SIGNAL
)) {
504 ngx_processes
[i
].exiting
= 1;
511 ngx_log_debug2(NGX_LOG_DEBUG_CORE
, cycle
->log
, 0,
512 "kill (%P, %d)" , ngx_processes
[i
].pid
, signo
);
514 if (kill(ngx_processes
[i
].pid
, signo
) == -1) {
516 ngx_log_error(NGX_LOG_ALERT
, cycle
->log
, err
,
517 "kill(%P, %d) failed",
518 ngx_processes
[i
].pid
, signo
);
520 if (err
== NGX_ESRCH
) {
521 ngx_processes
[i
].exited
= 1;
522 ngx_processes
[i
].exiting
= 0;
529 if (signo
!= ngx_signal_value(NGX_REOPEN_SIGNAL
)) {
530 ngx_processes
[i
].exiting
= 1;
537 ngx_reap_children(ngx_cycle_t
*cycle
)
542 ngx_core_conf_t
*ccf
;
544 ch
.command
= NGX_CMD_CLOSE_CHANNEL
;
548 for (i
= 0; i
< ngx_last_process
; i
++) {
550 ngx_log_debug7(NGX_LOG_DEBUG_EVENT
, cycle
->log
, 0,
551 "child: %d %P e:%d t:%d d:%d r:%d j:%d",
553 ngx_processes
[i
].pid
,
554 ngx_processes
[i
].exiting
,
555 ngx_processes
[i
].exited
,
556 ngx_processes
[i
].detached
,
557 ngx_processes
[i
].respawn
,
558 ngx_processes
[i
].just_spawn
);
560 if (ngx_processes
[i
].pid
== -1) {
564 if (ngx_processes
[i
].exited
) {
566 if (!ngx_processes
[i
].detached
) {
567 ngx_close_channel(ngx_processes
[i
].channel
, cycle
->log
);
569 ngx_processes
[i
].channel
[0] = -1;
570 ngx_processes
[i
].channel
[1] = -1;
572 ch
.pid
= ngx_processes
[i
].pid
;
575 for (n
= 0; n
< ngx_last_process
; n
++) {
576 if (ngx_processes
[n
].exited
577 || ngx_processes
[n
].pid
== -1
578 || ngx_processes
[n
].channel
[0] == -1)
583 ngx_log_debug3(NGX_LOG_DEBUG_CORE
, cycle
->log
, 0,
584 "pass close channel s:%i pid:%P to:%P",
585 ch
.slot
, ch
.pid
, ngx_processes
[n
].pid
);
587 /* TODO: NGX_AGAIN */
589 ngx_write_channel(ngx_processes
[n
].channel
[0],
590 &ch
, sizeof(ngx_channel_t
), cycle
->log
);
594 if (ngx_processes
[i
].respawn
595 && !ngx_processes
[i
].exiting
599 if (ngx_spawn_process(cycle
, ngx_processes
[i
].proc
,
600 ngx_processes
[i
].data
,
601 ngx_processes
[i
].name
, i
)
604 ngx_log_error(NGX_LOG_ALERT
, cycle
->log
, 0,
605 "can not respawn %s", ngx_processes
[i
].name
);
610 ch
.command
= NGX_CMD_OPEN_CHANNEL
;
611 ch
.pid
= ngx_processes
[ngx_process_slot
].pid
;
612 ch
.slot
= ngx_process_slot
;
613 ch
.fd
= ngx_processes
[ngx_process_slot
].channel
[0];
615 ngx_pass_open_channel(cycle
, &ch
);
622 if (ngx_processes
[i
].pid
== ngx_new_binary
) {
624 ccf
= (ngx_core_conf_t
*) ngx_get_conf(cycle
->conf_ctx
,
627 if (ngx_rename_file((char *) ccf
->oldpid
.data
,
628 (char *) ccf
->pid
.data
)
631 ngx_log_error(NGX_LOG_ALERT
, cycle
->log
, ngx_errno
,
632 ngx_rename_file_n
" %s back to %s failed "
633 "after the new binary process \"%s\" exited",
634 ccf
->oldpid
.data
, ccf
->pid
.data
, ngx_argv
[0]);
638 if (ngx_noaccepting
) {
644 if (i
== ngx_last_process
- 1) {
648 ngx_processes
[i
].pid
= -1;
651 } else if (ngx_processes
[i
].exiting
|| !ngx_processes
[i
].detached
) {
661 ngx_master_process_exit(ngx_cycle_t
*cycle
)
665 ngx_delete_pidfile(cycle
);
667 ngx_log_error(NGX_LOG_NOTICE
, cycle
->log
, 0, "exit");
669 for (i
= 0; ngx_modules
[i
]; i
++) {
670 if (ngx_modules
[i
]->exit_master
) {
671 ngx_modules
[i
]->exit_master(cycle
);
676 * Copy ngx_cycle->log related data to the special static exit cycle,
677 * log, and log file structures enough to allow a signal handler to log.
678 * The handler may be called when standard ngx_cycle->log allocated from
679 * ngx_cycle->pool is already destroyed.
682 ngx_exit_log_file
.fd
= ngx_cycle
->log
->file
->fd
;
684 ngx_exit_log
= *ngx_cycle
->log
;
685 ngx_exit_log
.file
= &ngx_exit_log_file
;
687 ngx_exit_cycle
.log
= &ngx_exit_log
;
688 ngx_cycle
= &ngx_exit_cycle
;
690 ngx_destroy_pool(cycle
->pool
);
697 ngx_worker_process_cycle(ngx_cycle_t
*cycle
, void *data
)
702 ngx_worker_process_init(cycle
, 1);
704 ngx_setproctitle("worker process");
710 ngx_core_conf_t
*ccf
;
712 ccf
= (ngx_core_conf_t
*) ngx_get_conf(cycle
->conf_ctx
, ngx_core_module
);
715 if (ngx_init_threads(ngx_threads_n
, ccf
->thread_stack_size
, cycle
)
722 err
= ngx_thread_key_create(&ngx_core_tls_key
);
724 ngx_log_error(NGX_LOG_ALERT
, cycle
->log
, err
,
725 ngx_thread_key_create_n
" failed");
730 for (n
= 0; n
< ngx_threads_n
; n
++) {
732 ngx_threads
[n
].cv
= ngx_cond_init(cycle
->log
);
734 if (ngx_threads
[n
].cv
== NULL
) {
739 if (ngx_create_thread((ngx_tid_t
*) &ngx_threads
[n
].tid
,
740 ngx_worker_thread_cycle
,
741 (void *) &ngx_threads
[n
], cycle
->log
)
756 c
= cycle
->connections
;
758 for (i
= 0; i
< cycle
->connection_n
; i
++) {
762 if (c
[i
].fd
!= -1 && c
[i
].idle
) {
764 c
[i
].read
->handler(c
[i
].read
);
768 if (ngx_event_timer_rbtree
.root
== ngx_event_timer_rbtree
.sentinel
)
770 ngx_log_error(NGX_LOG_NOTICE
, cycle
->log
, 0, "exiting");
772 ngx_worker_process_exit(cycle
);
776 ngx_log_debug0(NGX_LOG_DEBUG_EVENT
, cycle
->log
, 0, "worker cycle");
778 ngx_process_events_and_timers(cycle
);
781 ngx_log_error(NGX_LOG_NOTICE
, cycle
->log
, 0, "exiting");
783 ngx_worker_process_exit(cycle
);
788 ngx_log_error(NGX_LOG_NOTICE
, cycle
->log
, 0,
789 "gracefully shutting down");
790 ngx_setproctitle("worker process is shutting down");
793 ngx_close_listening_sockets(cycle
);
800 ngx_log_error(NGX_LOG_NOTICE
, cycle
->log
, 0, "reopening logs");
801 ngx_reopen_files(cycle
, -1);
808 ngx_worker_process_init(ngx_cycle_t
*cycle
, ngx_uint_t priority
)
814 ngx_core_conf_t
*ccf
;
817 ngx_process
= NGX_PROCESS_WORKER
;
819 if (ngx_set_environment(cycle
, NULL
) == NULL
) {
824 ccf
= (ngx_core_conf_t
*) ngx_get_conf(cycle
->conf_ctx
, ngx_core_module
);
826 if (priority
&& ccf
->priority
!= 0) {
827 if (setpriority(PRIO_PROCESS
, 0, ccf
->priority
) == -1) {
828 ngx_log_error(NGX_LOG_ALERT
, cycle
->log
, ngx_errno
,
829 "setpriority(%d) failed", ccf
->priority
);
833 if (ccf
->rlimit_nofile
!= NGX_CONF_UNSET
) {
834 rlmt
.rlim_cur
= (rlim_t
) ccf
->rlimit_nofile
;
835 rlmt
.rlim_max
= (rlim_t
) ccf
->rlimit_nofile
;
837 if (setrlimit(RLIMIT_NOFILE
, &rlmt
) == -1) {
838 ngx_log_error(NGX_LOG_ALERT
, cycle
->log
, ngx_errno
,
839 "setrlimit(RLIMIT_NOFILE, %i) failed",
844 if (ccf
->rlimit_core
!= NGX_CONF_UNSET_SIZE
) {
845 rlmt
.rlim_cur
= (rlim_t
) ccf
->rlimit_core
;
846 rlmt
.rlim_max
= (rlim_t
) ccf
->rlimit_core
;
848 if (setrlimit(RLIMIT_CORE
, &rlmt
) == -1) {
849 ngx_log_error(NGX_LOG_ALERT
, cycle
->log
, ngx_errno
,
850 "setrlimit(RLIMIT_CORE, %i) failed",
855 #ifdef RLIMIT_SIGPENDING
856 if (ccf
->rlimit_sigpending
!= NGX_CONF_UNSET
) {
857 rlmt
.rlim_cur
= (rlim_t
) ccf
->rlimit_sigpending
;
858 rlmt
.rlim_max
= (rlim_t
) ccf
->rlimit_sigpending
;
860 if (setrlimit(RLIMIT_SIGPENDING
, &rlmt
) == -1) {
861 ngx_log_error(NGX_LOG_ALERT
, cycle
->log
, ngx_errno
,
862 "setrlimit(RLIMIT_SIGPENDING, %i) failed",
863 ccf
->rlimit_sigpending
);
868 #ifdef NGX_HAVE_CAPABILITIES
869 if (ccf
->use_bind_capability
&& ngx_clear_capability(cycle
->log
) != NGX_OK
) {
874 if (ngx_switch_user(cycle
) == NGX_ERROR
) {
878 #if (NGX_HAVE_SCHED_SETAFFINITY)
881 ngx_log_error(NGX_LOG_NOTICE
, cycle
->log
, 0,
882 "sched_setaffinity(0x%08Xl)", cpu_affinity
);
884 if (sched_setaffinity(0, 32, (cpu_set_t
*) &cpu_affinity
) == -1) {
885 ngx_log_error(NGX_LOG_ALERT
, cycle
->log
, ngx_errno
,
886 "sched_setaffinity(0x%08Xl) failed", cpu_affinity
);
892 #if (NGX_HAVE_PR_SET_DUMPABLE)
894 /* allow coredump after setuid() in Linux 2.4.x */
896 if (prctl(PR_SET_DUMPABLE
, 1, 0, 0, 0) == -1) {
897 ngx_log_error(NGX_LOG_ALERT
, cycle
->log
, ngx_errno
,
898 "prctl(PR_SET_DUMPABLE) failed");
903 if (ccf
->working_directory
.len
) {
904 if (chdir((char *) ccf
->working_directory
.data
) == -1) {
905 ngx_log_error(NGX_LOG_ALERT
, cycle
->log
, ngx_errno
,
906 "chdir(\"%s\") failed", ccf
->working_directory
.data
);
914 if (sigprocmask(SIG_SETMASK
, &set
, NULL
) == -1) {
915 ngx_log_error(NGX_LOG_ALERT
, cycle
->log
, ngx_errno
,
916 "sigprocmask() failed");
920 * disable deleting previous events for the listening sockets because
921 * in the worker processes there are no events at all at this point
923 ls
= cycle
->listening
.elts
;
924 for (i
= 0; i
< cycle
->listening
.nelts
; i
++) {
925 ls
[i
].previous
= NULL
;
928 for (i
= 0; ngx_modules
[i
]; i
++) {
929 if (ngx_modules
[i
]->init_process
) {
930 if (ngx_modules
[i
]->init_process(cycle
) == NGX_ERROR
) {
937 for (n
= 0; n
< ngx_last_process
; n
++) {
939 if (ngx_processes
[n
].pid
== -1) {
943 if (n
== ngx_process_slot
) {
947 if (ngx_processes
[n
].channel
[1] == -1) {
951 if (close(ngx_processes
[n
].channel
[1]) == -1) {
952 ngx_log_error(NGX_LOG_ALERT
, cycle
->log
, ngx_errno
,
953 "close() channel failed");
957 if (close(ngx_processes
[ngx_process_slot
].channel
[0]) == -1) {
958 ngx_log_error(NGX_LOG_ALERT
, cycle
->log
, ngx_errno
,
959 "close() channel failed");
963 ngx_last_process
= 0;
966 if (ngx_add_channel_event(cycle
, ngx_channel
, NGX_READ_EVENT
,
977 ngx_worker_process_exit(ngx_cycle_t
*cycle
)
985 ngx_wakeup_worker_threads(cycle
);
988 for (i
= 0; ngx_modules
[i
]; i
++) {
989 if (ngx_modules
[i
]->exit_process
) {
990 ngx_modules
[i
]->exit_process(cycle
);
995 c
= cycle
->connections
;
996 for (i
= 0; i
< cycle
->connection_n
; i
++) {
999 && !c
[i
].read
->accept
1000 && !c
[i
].read
->channel
1001 && !c
[i
].read
->resolver
)
1003 ngx_log_error(NGX_LOG_ALERT
, cycle
->log
, 0,
1004 "open socket #%d left in connection %ui",
1010 if (ngx_debug_quit
) {
1011 ngx_log_error(NGX_LOG_ALERT
, cycle
->log
, 0, "aborting");
1017 * Copy ngx_cycle->log related data to the special static exit cycle,
1018 * log, and log file structures enough to allow a signal handler to log.
1019 * The handler may be called when standard ngx_cycle->log allocated from
1020 * ngx_cycle->pool is already destroyed.
1023 ngx_exit_log_file
.fd
= ngx_cycle
->log
->file
->fd
;
1025 ngx_exit_log
= *ngx_cycle
->log
;
1026 ngx_exit_log
.file
= &ngx_exit_log_file
;
1028 ngx_exit_cycle
.log
= &ngx_exit_log
;
1029 ngx_cycle
= &ngx_exit_cycle
;
1031 ngx_destroy_pool(cycle
->pool
);
1033 ngx_log_error(NGX_LOG_NOTICE
, ngx_cycle
->log
, 0, "exit");
1040 ngx_channel_handler(ngx_event_t
*ev
)
1044 ngx_connection_t
*c
;
1053 ngx_log_debug0(NGX_LOG_DEBUG_CORE
, ev
->log
, 0, "channel handler");
1057 n
= ngx_read_channel(c
->fd
, &ch
, sizeof(ngx_channel_t
), ev
->log
);
1059 ngx_log_debug1(NGX_LOG_DEBUG_CORE
, ev
->log
, 0, "channel: %i", n
);
1061 if (n
== NGX_ERROR
) {
1063 if (ngx_event_flags
& NGX_USE_EPOLL_EVENT
) {
1067 ngx_close_connection(c
);
1071 if (ngx_event_flags
& NGX_USE_EVENTPORT_EVENT
) {
1072 if (ngx_add_event(ev
, NGX_READ_EVENT
, 0) == NGX_ERROR
) {
1077 if (n
== NGX_AGAIN
) {
1081 ngx_log_debug1(NGX_LOG_DEBUG_CORE
, ev
->log
, 0,
1082 "channel command: %d", ch
.command
);
1084 switch (ch
.command
) {
1090 case NGX_CMD_TERMINATE
:
1094 case NGX_CMD_REOPEN
:
1098 case NGX_CMD_OPEN_CHANNEL
:
1100 ngx_log_debug3(NGX_LOG_DEBUG_CORE
, ev
->log
, 0,
1101 "get channel s:%i pid:%P fd:%d",
1102 ch
.slot
, ch
.pid
, ch
.fd
);
1104 ngx_processes
[ch
.slot
].pid
= ch
.pid
;
1105 ngx_processes
[ch
.slot
].channel
[0] = ch
.fd
;
1108 case NGX_CMD_CLOSE_CHANNEL
:
1110 ngx_log_debug4(NGX_LOG_DEBUG_CORE
, ev
->log
, 0,
1111 "close channel s:%i pid:%P our:%P fd:%d",
1112 ch
.slot
, ch
.pid
, ngx_processes
[ch
.slot
].pid
,
1113 ngx_processes
[ch
.slot
].channel
[0]);
1115 if (close(ngx_processes
[ch
.slot
].channel
[0]) == -1) {
1116 ngx_log_error(NGX_LOG_ALERT
, ev
->log
, ngx_errno
,
1117 "close() channel failed");
1120 ngx_processes
[ch
.slot
].channel
[0] = -1;
1130 ngx_wakeup_worker_threads(ngx_cycle_t
*cycle
)
1139 for (i
= 0; i
< ngx_threads_n
; i
++) {
1140 if (ngx_threads
[i
].state
< NGX_THREAD_EXIT
) {
1141 if (ngx_cond_signal(ngx_threads
[i
].cv
) == NGX_ERROR
) {
1142 ngx_threads
[i
].state
= NGX_THREAD_DONE
;
1149 if (ngx_threads
[i
].state
== NGX_THREAD_EXIT
) {
1150 ngx_thread_join(ngx_threads
[i
].tid
, NULL
);
1151 ngx_threads
[i
].state
= NGX_THREAD_DONE
;
1156 ngx_log_debug0(NGX_LOG_DEBUG_CORE
, cycle
->log
, 0,
1157 "all worker threads are joined");
1160 ngx_done_events(cycle
);
1161 ngx_mutex_destroy(ngx_event_timer_mutex
);
1162 ngx_mutex_destroy(ngx_posted_events_mutex
);
1172 static ngx_thread_value_t
1173 ngx_worker_thread_cycle(void *data
)
1175 ngx_thread_t
*thr
= data
;
1179 ngx_core_tls_t
*tls
;
1182 cycle
= (ngx_cycle_t
*) ngx_cycle
;
1185 sigaddset(&set
, ngx_signal_value(NGX_RECONFIGURE_SIGNAL
));
1186 sigaddset(&set
, ngx_signal_value(NGX_REOPEN_SIGNAL
));
1187 sigaddset(&set
, ngx_signal_value(NGX_CHANGEBIN_SIGNAL
));
1189 err
= ngx_thread_sigmask(SIG_BLOCK
, &set
, NULL
);
1191 ngx_log_error(NGX_LOG_ALERT
, cycle
->log
, err
,
1192 ngx_thread_sigmask_n
" failed");
1193 return (ngx_thread_value_t
) 1;
1196 ngx_log_debug1(NGX_LOG_DEBUG_CORE
, cycle
->log
, 0,
1197 "thread " NGX_TID_T_FMT
" started", ngx_thread_self());
1199 ngx_setthrtitle("worker thread");
1201 tls
= ngx_calloc(sizeof(ngx_core_tls_t
), cycle
->log
);
1203 return (ngx_thread_value_t
) 1;
1206 err
= ngx_thread_set_tls(ngx_core_tls_key
, tls
);
1208 ngx_log_error(NGX_LOG_ALERT
, cycle
->log
, err
,
1209 ngx_thread_set_tls_n
" failed");
1210 return (ngx_thread_value_t
) 1;
1213 ngx_mutex_lock(ngx_posted_events_mutex
);
1216 thr
->state
= NGX_THREAD_FREE
;
1218 if (ngx_cond_wait(thr
->cv
, ngx_posted_events_mutex
) == NGX_ERROR
) {
1219 return (ngx_thread_value_t
) 1;
1222 if (ngx_terminate
) {
1223 thr
->state
= NGX_THREAD_EXIT
;
1225 ngx_mutex_unlock(ngx_posted_events_mutex
);
1227 ngx_log_debug1(NGX_LOG_DEBUG_CORE
, cycle
->log
, 0,
1228 "thread " NGX_TID_T_FMT
" is done",
1231 return (ngx_thread_value_t
) 0;
1234 thr
->state
= NGX_THREAD_BUSY
;
1236 if (ngx_event_thread_process_posted(cycle
) == NGX_ERROR
) {
1237 return (ngx_thread_value_t
) 1;
1240 if (ngx_event_thread_process_posted(cycle
) == NGX_ERROR
) {
1241 return (ngx_thread_value_t
) 1;
1244 if (ngx_process_changes
) {
1245 if (ngx_process_changes(cycle
, 1) == NGX_ERROR
) {
1246 return (ngx_thread_value_t
) 1;
1256 ngx_cache_manager_process_cycle(ngx_cycle_t
*cycle
, void *data
)
1258 ngx_cache_manager_ctx_t
*ctx
= data
;
1263 cycle
->connection_n
= 512;
1265 ngx_worker_process_init(cycle
, 0);
1267 ngx_close_listening_sockets(cycle
);
1269 ngx_memzero(&ev
, sizeof(ngx_event_t
));
1270 ev
.handler
= ctx
->handler
;
1272 ev
.log
= cycle
->log
;
1273 ident
[3] = (void *) -1;
1275 ngx_use_accept_mutex
= 0;
1277 ngx_setproctitle(ctx
->name
);
1279 ngx_add_timer(&ev
, ctx
->delay
);
1283 if (ngx_terminate
|| ngx_quit
) {
1284 ngx_log_error(NGX_LOG_NOTICE
, cycle
->log
, 0, "exiting");
1290 ngx_log_error(NGX_LOG_NOTICE
, cycle
->log
, 0, "reopening logs");
1291 ngx_reopen_files(cycle
, -1);
1294 ngx_process_events_and_timers(cycle
);
1300 ngx_cache_manager_process_handler(ngx_event_t
*ev
)
1308 path
= ngx_cycle
->pathes
.elts
;
1309 for (i
= 0; i
< ngx_cycle
->pathes
.nelts
; i
++) {
1311 if (path
[i
]->manager
) {
1312 n
= path
[i
]->manager(path
[i
]->data
);
1314 next
= (n
<= next
) ? n
: next
;
1316 ngx_time_update(0, 0);
1324 ngx_add_timer(ev
, next
* 1000);
1329 ngx_cache_loader_process_handler(ngx_event_t
*ev
)
1335 cycle
= (ngx_cycle_t
*) ngx_cycle
;
1337 path
= cycle
->pathes
.elts
;
1338 for (i
= 0; i
< cycle
->pathes
.nelts
; i
++) {
1340 if (ngx_terminate
|| ngx_quit
) {
1344 if (path
[i
]->loader
) {
1345 path
[i
]->loader(path
[i
]->data
);
1346 ngx_time_update(0, 0);