diff options
Diffstat (limited to '')
-rw-r--r-- | src/nxt_worker_process.c | 213 |
1 files changed, 213 insertions, 0 deletions
diff --git a/src/nxt_worker_process.c b/src/nxt_worker_process.c new file mode 100644 index 00000000..6f64b8f9 --- /dev/null +++ b/src/nxt_worker_process.c @@ -0,0 +1,213 @@ + +/* + * Copyright (C) Igor Sysoev + * Copyright (C) NGINX, Inc. + */ + +#include <nxt_main.h> +#include <nxt_cycle.h> +#include <nxt_process_chan.h> +#include <nxt_master_process.h> + + +static void nxt_worker_process_quit(nxt_thread_t *thr); +static void nxt_worker_process_quit_handler(nxt_thread_t *thr, + nxt_chan_recv_msg_t *msg); +static void nxt_worker_process_signal_handler(nxt_thread_t *thr, void *obj, + void *data); +static void nxt_worker_process_sigterm_handler(nxt_thread_t *thr, void *obj, + void *data); +static void nxt_worker_process_sigquit_handler(nxt_thread_t *thr, void *obj, + void *data); + + +static nxt_process_chan_handler_t nxt_worker_process_chan_handlers[] = { + nxt_worker_process_quit_handler, + nxt_process_chan_new_handler, + nxt_process_chan_change_log_file_handler, + nxt_process_chan_data_handler, +}; + + +static const nxt_event_sig_t nxt_worker_process_signals[] = { + nxt_event_signal(SIGHUP, nxt_worker_process_signal_handler), + nxt_event_signal(SIGINT, nxt_worker_process_sigterm_handler), + nxt_event_signal(SIGQUIT, nxt_worker_process_sigterm_handler), + nxt_event_signal(SIGTERM, nxt_worker_process_sigquit_handler), + nxt_event_signal(SIGCHLD, nxt_worker_process_signal_handler), + nxt_event_signal(SIGUSR1, nxt_worker_process_signal_handler), + nxt_event_signal(SIGUSR1, nxt_worker_process_signal_handler), + nxt_event_signal_end, +}; + + +void +nxt_worker_process_start(void *data) +{ + nxt_int_t n; + nxt_cycle_t *cycle; + nxt_thread_t *thr; + nxt_process_chan_t *proc; + const nxt_event_set_ops_t *event_set; + + cycle = data; + + nxt_thread_init_data(nxt_thread_cycle_data); + nxt_thread_cycle_set(cycle); + + thr = nxt_thread(); + + nxt_log_error(NXT_LOG_INFO, thr->log, "worker process"); + + nxt_process_title("nginman: worker process"); + + cycle->type = NXT_PROCESS_WORKER; + + nxt_random_init(&nxt_random_data); + + if (getuid() == 0) { + /* Super-user. */ + + n = nxt_user_cred_set(&cycle->user_cred); + if (n != NXT_OK) { + goto fail; + } + } + + /* Update inherited master process event engine and signals processing. */ + thr->engine->signals->sigev = nxt_worker_process_signals; + + event_set = nxt_service_get(cycle->services, "engine", cycle->engine); + if (event_set == NULL) { + goto fail; + } + + if (nxt_event_engine_change(thr, event_set, cycle->batch) != NXT_OK) { + goto fail; + } + +#if 0 + if (nxt_cycle_listen_sockets_enable(thr, cycle) != NXT_OK) { + goto fail; + } +#endif + + proc = cycle->processes->elts; + + /* A master process chan. */ + nxt_chan_read_close(proc[0].chan); + nxt_chan_write_enable(thr, proc[0].chan); + + /* A worker process chan. */ + nxt_process_chan_create(thr, &proc[cycle->current_process], + nxt_worker_process_chan_handlers); + +#if (NXT_THREADS) + { + nxt_int_t ret; + + ret = nxt_cycle_thread_pool_create(thr, cycle, cycle->auxiliary_threads, + 60000 * 1000000LL); + + if (nxt_slow_path(ret != NXT_OK)) { + goto fail; + } + } + + nxt_app_start(cycle); +#endif + + return; + +fail: + + exit(1); + nxt_unreachable(); +} + + +static void +nxt_worker_process_quit(nxt_thread_t *thr) +{ + nxt_uint_t n; + nxt_cycle_t *cycle; + nxt_queue_t *listen; + nxt_queue_link_t *link, *next; + nxt_listen_socket_t *ls; + nxt_event_conn_listen_t *cls; + + cycle = nxt_thread_cycle(); + + nxt_log_debug(thr->log, "close listen connections"); + + listen = &thr->engine->listen_connections; + + for (link = nxt_queue_first(listen); + link != nxt_queue_tail(listen); + link = next) + { + next = nxt_queue_next(link); + cls = nxt_queue_link_data(link, nxt_event_conn_listen_t, link); + nxt_queue_remove(link); + + nxt_event_fd_close(thr->engine, &cls->socket); + } + + if (cycle->listen_sockets != NULL) { + + ls = cycle->listen_sockets->elts; + n = cycle->listen_sockets->nelts; + + while (n != 0) { + nxt_socket_close(ls->socket); + ls->socket = -1; + + ls++; + n--; + } + + cycle->listen_sockets->nelts = 0; + } + + nxt_cycle_quit(thr, cycle); +} + + +static void +nxt_worker_process_signal_handler(nxt_thread_t *thr, void *obj, void *data) +{ + nxt_log_error(NXT_LOG_INFO, thr->log, + "signal signo:%d (%s) recevied, ignored", + (int) (uintptr_t) obj, data); +} + + +static void +nxt_worker_process_quit_handler(nxt_thread_t *thr, nxt_chan_recv_msg_t *msg) +{ + nxt_worker_process_quit(thr); +} + + +static void +nxt_worker_process_sigterm_handler(nxt_thread_t *thr, void *obj, void *data) +{ + nxt_log_debug(thr->log, "sigterm handler signo:%d (%s)", + (int) (uintptr_t) obj, data); + + /* A fast exit. */ + + nxt_cycle_quit(thr, NULL); +} + + +static void +nxt_worker_process_sigquit_handler(nxt_thread_t *thr, void *obj, void *data) +{ + nxt_log_debug(thr->log, "sigquit handler signo:%d (%s)", + (int) (uintptr_t) obj, data); + + /* A graceful exit. */ + + nxt_worker_process_quit(thr); +} |