Processes refactoring.
The cycle has been renamed to the runtime.
This commit is contained in:
@@ -237,7 +237,7 @@ fi
|
|||||||
|
|
||||||
cat << END > Makefile
|
cat << END > Makefile
|
||||||
|
|
||||||
all: libnxt $NXT_BIN
|
all: $NXT_BIN
|
||||||
|
|
||||||
libnxt:
|
libnxt:
|
||||||
make -f $NXT_MAKEFILE libnxt
|
make -f $NXT_MAKEFILE libnxt
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ NXT_MODULES_SRC=$NXT_BUILD_DIR/nxt_modules.c
|
|||||||
cat << END > $NXT_MODULES_SRC
|
cat << END > $NXT_MODULES_SRC
|
||||||
|
|
||||||
#include <nxt_main.h>
|
#include <nxt_main.h>
|
||||||
#include <nxt_cycle.h>
|
#include <nxt_runtime.h>
|
||||||
|
|
||||||
|
|
||||||
END
|
END
|
||||||
@@ -26,7 +26,7 @@ END
|
|||||||
|
|
||||||
for nxt_init in $NXT_MODULES_INIT
|
for nxt_init in $NXT_MODULES_INIT
|
||||||
do
|
do
|
||||||
$echo "extern nxt_int_t $nxt_init(nxt_thread_t *thr, nxt_cycle_t *cycle);" \
|
$echo "extern nxt_int_t $nxt_init(nxt_thread_t *thr, nxt_runtime_t *rt);" \
|
||||||
>> $NXT_MODULES_SRC
|
>> $NXT_MODULES_SRC
|
||||||
done
|
done
|
||||||
|
|
||||||
|
|||||||
10
auto/sources
10
auto/sources
@@ -82,6 +82,7 @@ NXT_LIB_SRCS=" \
|
|||||||
src/nxt_process_title.c \
|
src/nxt_process_title.c \
|
||||||
src/nxt_signal.c \
|
src/nxt_signal.c \
|
||||||
src/nxt_port_socket.c \
|
src/nxt_port_socket.c \
|
||||||
|
src/nxt_port.c \
|
||||||
src/nxt_dyld.c \
|
src/nxt_dyld.c \
|
||||||
src/nxt_random.c \
|
src/nxt_random.c \
|
||||||
src/nxt_queue.c \
|
src/nxt_queue.c \
|
||||||
@@ -320,7 +321,7 @@ if [ $NXT_LIB_UNIT_TEST = YES ]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
NXT_DEPS=" \
|
NXT_DEPS=" \
|
||||||
src/nxt_cycle.h \
|
src/nxt_runtime.h \
|
||||||
src/nxt_application.h \
|
src/nxt_application.h \
|
||||||
src/nxt_master_process.h \
|
src/nxt_master_process.h \
|
||||||
"
|
"
|
||||||
@@ -328,10 +329,11 @@ NXT_DEPS=" \
|
|||||||
NXT_SRCS=" \
|
NXT_SRCS=" \
|
||||||
src/nxt_main.c \
|
src/nxt_main.c \
|
||||||
src/nxt_app_log.c \
|
src/nxt_app_log.c \
|
||||||
src/nxt_cycle.c \
|
src/nxt_runtime.c \
|
||||||
src/nxt_port.c \
|
|
||||||
src/nxt_application.c \
|
|
||||||
src/nxt_stream_module.c \
|
src/nxt_stream_module.c \
|
||||||
src/nxt_master_process.c \
|
src/nxt_master_process.c \
|
||||||
src/nxt_worker_process.c \
|
src/nxt_worker_process.c \
|
||||||
|
src/nxt_controller.c \
|
||||||
|
src/nxt_router.c \
|
||||||
|
src/nxt_application.c \
|
||||||
"
|
"
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <nxt_main.h>
|
#include <nxt_main.h>
|
||||||
#include <nxt_cycle.h>
|
#include <nxt_runtime.h>
|
||||||
|
|
||||||
|
|
||||||
static nxt_time_string_t nxt_log_error_time_cache;
|
static nxt_time_string_t nxt_log_error_time_cache;
|
||||||
|
|||||||
@@ -6,13 +6,14 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <nxt_main.h>
|
#include <nxt_main.h>
|
||||||
#include <nxt_cycle.h>
|
#include <nxt_runtime.h>
|
||||||
#include <nxt_application.h>
|
#include <nxt_application.h>
|
||||||
|
|
||||||
|
|
||||||
#define NXT_PARSE_AGAIN (u_char *) -1
|
#define NXT_PARSE_AGAIN (u_char *) -1
|
||||||
|
|
||||||
|
|
||||||
|
static nxt_int_t nxt_app_listen_socket(nxt_task_t *task, nxt_runtime_t *rt);
|
||||||
static void nxt_app_thread(void *ctx);
|
static void nxt_app_thread(void *ctx);
|
||||||
static nxt_app_request_t *nxt_app_request_create(nxt_socket_t s,
|
static nxt_app_request_t *nxt_app_request_create(nxt_socket_t s,
|
||||||
nxt_log_t *log);
|
nxt_log_t *log);
|
||||||
@@ -77,11 +78,15 @@ static nxt_uint_t nxt_app_buf_max_number = 16;
|
|||||||
|
|
||||||
|
|
||||||
nxt_int_t
|
nxt_int_t
|
||||||
nxt_app_start(nxt_cycle_t *cycle)
|
nxt_app_start(nxt_task_t *task, nxt_runtime_t *rt)
|
||||||
{
|
{
|
||||||
nxt_thread_link_t *link;
|
nxt_thread_link_t *link;
|
||||||
nxt_thread_handle_t handle;
|
nxt_thread_handle_t handle;
|
||||||
|
|
||||||
|
if (nxt_app_listen_socket(task, rt) != NXT_OK) {
|
||||||
|
return NXT_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
if (nxt_slow_path(nxt_thread_mutex_create(&nxt_app_mutex) != NXT_OK)) {
|
if (nxt_slow_path(nxt_thread_mutex_create(&nxt_app_mutex) != NXT_OK)) {
|
||||||
return NXT_ERROR;
|
return NXT_ERROR;
|
||||||
}
|
}
|
||||||
@@ -94,7 +99,7 @@ nxt_app_start(nxt_cycle_t *cycle)
|
|||||||
|
|
||||||
if (nxt_fast_path(link != NULL)) {
|
if (nxt_fast_path(link != NULL)) {
|
||||||
link->start = nxt_app_thread;
|
link->start = nxt_app_thread;
|
||||||
link->data = cycle;
|
link->data = rt;
|
||||||
|
|
||||||
return nxt_thread_create(&handle, link);
|
return nxt_thread_create(&handle, link);
|
||||||
}
|
}
|
||||||
@@ -103,6 +108,39 @@ nxt_app_start(nxt_cycle_t *cycle)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static nxt_int_t
|
||||||
|
nxt_app_listen_socket(nxt_task_t *task, nxt_runtime_t *rt)
|
||||||
|
{
|
||||||
|
nxt_sockaddr_t *sa;
|
||||||
|
nxt_listen_socket_t *ls;
|
||||||
|
|
||||||
|
sa = nxt_sockaddr_alloc(rt->mem_pool, sizeof(struct sockaddr_in),
|
||||||
|
NXT_INET_ADDR_STR_LEN);
|
||||||
|
if (sa == NULL) {
|
||||||
|
return NXT_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
sa->type = SOCK_STREAM;
|
||||||
|
sa->u.sockaddr_in.sin_family = AF_INET;
|
||||||
|
sa->u.sockaddr_in.sin_port = htons(8080);
|
||||||
|
|
||||||
|
nxt_sockaddr_text(sa);
|
||||||
|
|
||||||
|
ls = nxt_runtime_listen_socket_add(rt, sa);
|
||||||
|
if (ls == NULL) {
|
||||||
|
return NXT_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
ls->read_after_accept = 1;
|
||||||
|
|
||||||
|
if (nxt_listen_socket_create(task, ls, 0) != NXT_OK) {
|
||||||
|
return NXT_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NXT_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#define SIZE 4096
|
#define SIZE 4096
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -110,9 +148,9 @@ nxt_app_thread(void *ctx)
|
|||||||
{
|
{
|
||||||
ssize_t n;
|
ssize_t n;
|
||||||
nxt_err_t err;
|
nxt_err_t err;
|
||||||
nxt_cycle_t *cycle;
|
|
||||||
nxt_socket_t s;
|
nxt_socket_t s;
|
||||||
nxt_thread_t *thr;
|
nxt_thread_t *thr;
|
||||||
|
nxt_runtime_t *rt;
|
||||||
nxt_app_request_t *r;
|
nxt_app_request_t *r;
|
||||||
nxt_event_engine_t **engines;
|
nxt_event_engine_t **engines;
|
||||||
nxt_listen_socket_t *ls;
|
nxt_listen_socket_t *ls;
|
||||||
@@ -124,8 +162,8 @@ nxt_app_thread(void *ctx)
|
|||||||
|
|
||||||
nxt_log_debug(thr->log, "app thread");
|
nxt_log_debug(thr->log, "app thread");
|
||||||
|
|
||||||
cycle = ctx;
|
rt = ctx;
|
||||||
engines = cycle->engines->elts;
|
engines = rt->engines->elts;
|
||||||
|
|
||||||
nxt_app_engine = engines[0];
|
nxt_app_engine = engines[0];
|
||||||
|
|
||||||
@@ -138,7 +176,7 @@ nxt_app_thread(void *ctx)
|
|||||||
nxt_log_debug(thr->log, "application init failed");
|
nxt_log_debug(thr->log, "application init failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
ls = cycle->listen_sockets->elts;
|
ls = rt->listen_sockets->elts;
|
||||||
|
|
||||||
for ( ;; ) {
|
for ( ;; ) {
|
||||||
nxt_log_debug(thr->log, "wait on accept");
|
nxt_log_debug(thr->log, "wait on accept");
|
||||||
|
|||||||
@@ -53,7 +53,8 @@ typedef struct {
|
|||||||
extern nxt_application_module_t nxt_python_module;
|
extern nxt_application_module_t nxt_python_module;
|
||||||
|
|
||||||
|
|
||||||
nxt_int_t nxt_app_http_read_body(nxt_app_request_t *r, u_char *data, size_t len);
|
nxt_int_t nxt_app_http_read_body(nxt_app_request_t *r, u_char *data,
|
||||||
|
size_t len);
|
||||||
nxt_int_t nxt_app_write(nxt_app_request_t *r, const u_char *data, size_t len);
|
nxt_int_t nxt_app_write(nxt_app_request_t *r, const u_char *data, size_t len);
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
254
src/nxt_controller.c
Normal file
254
src/nxt_controller.c
Normal file
@@ -0,0 +1,254 @@
|
|||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) Igor Sysoev
|
||||||
|
* Copyright (C) Valentin V. Bartenev
|
||||||
|
* Copyright (C) NGINX, Inc.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <nxt_main.h>
|
||||||
|
#include <nxt_runtime.h>
|
||||||
|
#include <nxt_master_process.h>
|
||||||
|
|
||||||
|
|
||||||
|
static void nxt_controller_conn_init(nxt_task_t *task, void *obj, void *data);
|
||||||
|
static void nxt_controller_conn_read(nxt_task_t *task, void *obj, void *data);
|
||||||
|
static nxt_msec_t nxt_controller_conn_timeout_value(nxt_event_conn_t *c,
|
||||||
|
uintptr_t data);
|
||||||
|
static void nxt_controller_conn_read_error(nxt_task_t *task, void *obj,
|
||||||
|
void *data);
|
||||||
|
static void nxt_controller_conn_read_timeout(nxt_task_t *task, void *obj,
|
||||||
|
void *data);
|
||||||
|
static void nxt_controller_conn_close(nxt_task_t *task, void *obj, void *data);
|
||||||
|
static void nxt_controller_conn_free(nxt_task_t *task, void *obj, void *data);
|
||||||
|
|
||||||
|
|
||||||
|
static const nxt_event_conn_state_t nxt_controller_conn_read_state;
|
||||||
|
static const nxt_event_conn_state_t nxt_controller_conn_close_state;
|
||||||
|
|
||||||
|
|
||||||
|
nxt_int_t
|
||||||
|
nxt_controller_start(nxt_task_t *task, nxt_runtime_t *rt)
|
||||||
|
{
|
||||||
|
if (nxt_event_conn_listen(task, rt->controller_socket) != NXT_OK) {
|
||||||
|
return NXT_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NXT_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
nxt_int_t
|
||||||
|
nxt_runtime_controller_socket(nxt_task_t *task, nxt_runtime_t *rt)
|
||||||
|
{
|
||||||
|
nxt_sockaddr_t *sa;
|
||||||
|
nxt_listen_socket_t *ls;
|
||||||
|
|
||||||
|
sa = rt->controller_listen;
|
||||||
|
|
||||||
|
if (rt->controller_listen == NULL) {
|
||||||
|
sa = nxt_sockaddr_alloc(rt->mem_pool, sizeof(struct sockaddr_in),
|
||||||
|
NXT_INET_ADDR_STR_LEN);
|
||||||
|
if (sa == NULL) {
|
||||||
|
return NXT_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
sa->type = SOCK_STREAM;
|
||||||
|
sa->u.sockaddr_in.sin_family = AF_INET;
|
||||||
|
sa->u.sockaddr_in.sin_port = htons(8443);
|
||||||
|
|
||||||
|
nxt_sockaddr_text(sa);
|
||||||
|
|
||||||
|
rt->controller_listen = sa;
|
||||||
|
}
|
||||||
|
|
||||||
|
ls = nxt_mem_alloc(rt->mem_pool, sizeof(nxt_listen_socket_t));
|
||||||
|
if (ls == NULL) {
|
||||||
|
return NXT_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
ls->sockaddr = nxt_sockaddr_create(rt->mem_pool, &sa->u.sockaddr,
|
||||||
|
sa->socklen, sa->length);
|
||||||
|
if (ls->sockaddr == NULL) {
|
||||||
|
return NXT_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
ls->sockaddr->type = sa->type;
|
||||||
|
|
||||||
|
nxt_sockaddr_text(ls->sockaddr);
|
||||||
|
|
||||||
|
ls->socket = -1;
|
||||||
|
ls->backlog = NXT_LISTEN_BACKLOG;
|
||||||
|
ls->read_after_accept = 1;
|
||||||
|
ls->flags = NXT_NONBLOCK;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
/* STUB */
|
||||||
|
wq = nxt_mem_zalloc(cf->mem_pool, sizeof(nxt_work_queue_t));
|
||||||
|
if (wq == NULL) {
|
||||||
|
return NXT_ERROR;
|
||||||
|
}
|
||||||
|
nxt_work_queue_name(wq, "listen");
|
||||||
|
/**/
|
||||||
|
|
||||||
|
ls->work_queue = wq;
|
||||||
|
#endif
|
||||||
|
ls->handler = nxt_controller_conn_init;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Connection memory pool chunk size is tunned to
|
||||||
|
* allocate the most data in one mem_pool chunk.
|
||||||
|
*/
|
||||||
|
ls->mem_pool_size = nxt_listen_socket_pool_min_size(ls)
|
||||||
|
+ sizeof(nxt_event_conn_proxy_t)
|
||||||
|
+ sizeof(nxt_event_conn_t)
|
||||||
|
+ 4 * sizeof(nxt_buf_t);
|
||||||
|
|
||||||
|
if (nxt_listen_socket_create(task, ls, 0) != NXT_OK) {
|
||||||
|
return NXT_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
rt->controller_socket = ls;
|
||||||
|
|
||||||
|
return NXT_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
nxt_controller_conn_init(nxt_task_t *task, void *obj, void *data)
|
||||||
|
{
|
||||||
|
nxt_buf_t *b;
|
||||||
|
nxt_event_conn_t *c;
|
||||||
|
nxt_event_engine_t *engine;
|
||||||
|
|
||||||
|
c = obj;
|
||||||
|
|
||||||
|
nxt_debug(task, "controller conn init fd:%d", c->socket.fd);
|
||||||
|
|
||||||
|
b = nxt_buf_mem_alloc(c->mem_pool, 1024, 0);
|
||||||
|
if (nxt_slow_path(b == NULL)) {
|
||||||
|
nxt_controller_conn_free(task, c, NULL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
c->read = b;
|
||||||
|
c->socket.read_ready = 1;
|
||||||
|
c->read_state = &nxt_controller_conn_read_state;
|
||||||
|
|
||||||
|
engine = task->thread->engine;
|
||||||
|
c->read_work_queue = &engine->read_work_queue;
|
||||||
|
|
||||||
|
nxt_event_conn_read(engine, c);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static const nxt_event_conn_state_t nxt_controller_conn_read_state
|
||||||
|
nxt_aligned(64) =
|
||||||
|
{
|
||||||
|
NXT_EVENT_NO_BUF_PROCESS,
|
||||||
|
NXT_EVENT_TIMER_NO_AUTORESET,
|
||||||
|
|
||||||
|
nxt_controller_conn_read,
|
||||||
|
nxt_controller_conn_close,
|
||||||
|
nxt_controller_conn_read_error,
|
||||||
|
|
||||||
|
nxt_controller_conn_read_timeout,
|
||||||
|
nxt_controller_conn_timeout_value,
|
||||||
|
60 * 1000,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
nxt_controller_conn_read(nxt_task_t *task, void *obj, void *data)
|
||||||
|
{
|
||||||
|
nxt_event_conn_t *c;
|
||||||
|
|
||||||
|
c = obj;
|
||||||
|
|
||||||
|
nxt_debug(task, "controller conn read");
|
||||||
|
|
||||||
|
nxt_controller_conn_close(task, c, c->socket.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static nxt_msec_t
|
||||||
|
nxt_controller_conn_timeout_value(nxt_event_conn_t *c, uintptr_t data)
|
||||||
|
{
|
||||||
|
return (nxt_msec_t) data;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
nxt_controller_conn_read_error(nxt_task_t *task, void *obj, void *data)
|
||||||
|
{
|
||||||
|
nxt_event_conn_t *c;
|
||||||
|
|
||||||
|
c = obj;
|
||||||
|
|
||||||
|
nxt_debug(task, "controller conn read error");
|
||||||
|
|
||||||
|
nxt_controller_conn_close(task, c, c->socket.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
nxt_controller_conn_read_timeout(nxt_task_t *task, void *obj, void *data)
|
||||||
|
{
|
||||||
|
nxt_timer_t *ev;
|
||||||
|
nxt_event_conn_t *c;
|
||||||
|
|
||||||
|
ev = obj;
|
||||||
|
|
||||||
|
c = nxt_event_read_timer_conn(ev);
|
||||||
|
c->socket.timedout = 1;
|
||||||
|
c->socket.closed = 1;
|
||||||
|
|
||||||
|
nxt_debug(task, "controller conn read timeout");
|
||||||
|
|
||||||
|
nxt_controller_conn_close(task, c, c->socket.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static const nxt_event_conn_state_t nxt_controller_conn_close_state
|
||||||
|
nxt_aligned(64) =
|
||||||
|
{
|
||||||
|
NXT_EVENT_NO_BUF_PROCESS,
|
||||||
|
NXT_EVENT_TIMER_NO_AUTORESET,
|
||||||
|
|
||||||
|
nxt_controller_conn_free,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
0,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
nxt_controller_conn_close(nxt_task_t *task, void *obj, void *data)
|
||||||
|
{
|
||||||
|
nxt_event_conn_t *c;
|
||||||
|
|
||||||
|
c = obj;
|
||||||
|
|
||||||
|
nxt_debug(task, "controller conn close");
|
||||||
|
|
||||||
|
c->write_state = &nxt_controller_conn_close_state;
|
||||||
|
|
||||||
|
nxt_event_conn_close(task->thread->engine, c);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
nxt_controller_conn_free(nxt_task_t *task, void *obj, void *data)
|
||||||
|
{
|
||||||
|
nxt_event_conn_t *c;
|
||||||
|
|
||||||
|
c = obj;
|
||||||
|
|
||||||
|
nxt_debug(task, "controller conn free");
|
||||||
|
|
||||||
|
nxt_mem_pool_destroy(c->mem_pool);
|
||||||
|
|
||||||
|
//nxt_free(c);
|
||||||
|
}
|
||||||
1791
src/nxt_cycle.c
1791
src/nxt_cycle.c
File diff suppressed because it is too large
Load Diff
159
src/nxt_cycle.h
159
src/nxt_cycle.h
@@ -1,159 +0,0 @@
|
|||||||
|
|
||||||
/*
|
|
||||||
* Copyright (C) Igor Sysoev
|
|
||||||
* Copyright (C) Valentin V. Bartenev
|
|
||||||
* Copyright (C) NGINX, Inc.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _NXT_CYCLE_H_INCLUDED_
|
|
||||||
#define _NXT_CYCLE_H_INCLUDED_
|
|
||||||
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
NXT_PROCESS_SINGLE = 0,
|
|
||||||
NXT_PROCESS_MASTER,
|
|
||||||
NXT_PROCESS_WORKER,
|
|
||||||
} nxt_process_type_e;
|
|
||||||
|
|
||||||
|
|
||||||
typedef void (*nxt_cycle_cont_t)(nxt_task_t *task, nxt_cycle_t *cycle);
|
|
||||||
|
|
||||||
|
|
||||||
struct nxt_cycle_s {
|
|
||||||
nxt_mem_pool_t *mem_pool;
|
|
||||||
|
|
||||||
nxt_cycle_t *previous;
|
|
||||||
|
|
||||||
nxt_array_t *inherited_sockets; /* of nxt_listen_socket_t */
|
|
||||||
nxt_array_t *listen_sockets; /* of nxt_listen_socket_t */
|
|
||||||
|
|
||||||
nxt_array_t *services; /* of nxt_service_t */
|
|
||||||
nxt_array_t *engines; /* of nxt_event_engine_t */
|
|
||||||
|
|
||||||
nxt_cycle_cont_t start;
|
|
||||||
|
|
||||||
nxt_str_t *conf_prefix;
|
|
||||||
nxt_str_t *prefix;
|
|
||||||
|
|
||||||
nxt_str_t hostname;
|
|
||||||
|
|
||||||
nxt_file_name_t *pid_file;
|
|
||||||
nxt_file_name_t *oldbin_file;
|
|
||||||
nxt_pid_t new_binary;
|
|
||||||
|
|
||||||
#if (NXT_THREADS)
|
|
||||||
nxt_array_t *thread_pools; /* of nxt_thread_pool_t */
|
|
||||||
nxt_cycle_cont_t continuation;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
nxt_array_t *ports; /* of nxt_port_t */
|
|
||||||
|
|
||||||
nxt_list_t *log_files; /* of nxt_file_t */
|
|
||||||
|
|
||||||
nxt_array_t *shm_zones; /* of nxt_cycle_shm_zone_t */
|
|
||||||
|
|
||||||
uint32_t process_generation;
|
|
||||||
uint32_t current_process;
|
|
||||||
uint32_t last_engine_id;
|
|
||||||
|
|
||||||
nxt_process_type_e type;
|
|
||||||
|
|
||||||
uint8_t test_config; /* 1 bit */
|
|
||||||
uint8_t reconfiguring; /* 1 bit */
|
|
||||||
|
|
||||||
void **core_ctx;
|
|
||||||
|
|
||||||
nxt_timer_t timer;
|
|
||||||
|
|
||||||
uint8_t daemon;
|
|
||||||
uint8_t batch;
|
|
||||||
uint8_t master_process;
|
|
||||||
const char *engine;
|
|
||||||
uint32_t engine_connections;
|
|
||||||
uint32_t worker_processes;
|
|
||||||
uint32_t auxiliary_threads;
|
|
||||||
nxt_user_cred_t user_cred;
|
|
||||||
const char *group;
|
|
||||||
const char *pid;
|
|
||||||
const char *error_log;
|
|
||||||
|
|
||||||
nxt_sockaddr_t *app_listen;
|
|
||||||
nxt_sockaddr_t *stream_listen;
|
|
||||||
nxt_str_t upstream;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
void *addr;
|
|
||||||
size_t size;
|
|
||||||
nxt_uint_t page_size;
|
|
||||||
nxt_str_t name;
|
|
||||||
} nxt_cycle_shm_zone_t;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
typedef nxt_int_t (*nxt_module_init_t)(nxt_thread_t *thr, nxt_cycle_t *cycle);
|
|
||||||
|
|
||||||
|
|
||||||
nxt_thread_extern_data(nxt_cycle_t *, nxt_thread_cycle_data);
|
|
||||||
|
|
||||||
|
|
||||||
nxt_inline void
|
|
||||||
nxt_thread_cycle_set(nxt_cycle_t *cycle)
|
|
||||||
{
|
|
||||||
nxt_cycle_t **p;
|
|
||||||
|
|
||||||
p = nxt_thread_get_data(nxt_thread_cycle_data);
|
|
||||||
|
|
||||||
*p = cycle;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
nxt_inline nxt_cycle_t *
|
|
||||||
nxt_thread_cycle(void)
|
|
||||||
{
|
|
||||||
nxt_cycle_t **p;
|
|
||||||
|
|
||||||
p = nxt_thread_get_data(nxt_thread_cycle_data);
|
|
||||||
|
|
||||||
return *p;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
nxt_int_t nxt_cycle_create(nxt_thread_t *thr, nxt_task_t *task,
|
|
||||||
nxt_cycle_t *previous, nxt_cycle_cont_t start);
|
|
||||||
void nxt_cycle_quit(nxt_task_t *task, nxt_cycle_t *cycle);
|
|
||||||
|
|
||||||
void nxt_cycle_event_engine_free(nxt_cycle_t *cycle);
|
|
||||||
|
|
||||||
#if (NXT_THREADS)
|
|
||||||
nxt_int_t nxt_cycle_thread_pool_create(nxt_thread_t *thr, nxt_cycle_t *cycle,
|
|
||||||
nxt_uint_t max_threads, nxt_nsec_t timeout);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* STUB */
|
|
||||||
nxt_str_t *nxt_current_directory(nxt_mem_pool_t *mp);
|
|
||||||
|
|
||||||
nxt_int_t nxt_cycle_pid_file_create(nxt_file_name_t *pid_file, nxt_bool_t test);
|
|
||||||
|
|
||||||
nxt_listen_socket_t *nxt_cycle_listen_socket_add(nxt_cycle_t *cycle,
|
|
||||||
nxt_sockaddr_t *sa);
|
|
||||||
nxt_int_t nxt_cycle_listen_sockets_enable(nxt_task_t *task, nxt_cycle_t *cycle);
|
|
||||||
nxt_file_t *nxt_cycle_log_file_add(nxt_cycle_t *cycle, nxt_str_t *name);
|
|
||||||
|
|
||||||
nxt_int_t nxt_cycle_shm_zone_add(nxt_cycle_t *cycle, nxt_str_t *name,
|
|
||||||
size_t size, nxt_uint_t page_size);
|
|
||||||
|
|
||||||
/* STUB */
|
|
||||||
void nxt_cdecl nxt_log_time_handler(nxt_uint_t level, nxt_log_t *log,
|
|
||||||
const char *fmt, ...);
|
|
||||||
|
|
||||||
void nxt_stream_connection_init(nxt_task_t *task, void *obj, void *data);
|
|
||||||
nxt_int_t nxt_app_start(nxt_cycle_t *cycle);
|
|
||||||
|
|
||||||
|
|
||||||
extern nxt_module_init_t nxt_init_modules[];
|
|
||||||
extern nxt_uint_t nxt_init_modules_n;
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* _NXT_CYCLE_H_INCLIDED_ */
|
|
||||||
@@ -65,7 +65,7 @@ typedef struct {
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* The write() is an interface to write a buffer chain with a given rate
|
* The write() is an interface to write a buffer chain with a given rate
|
||||||
* limit. It calls write_chunk() in a cycle and handles write event timer.
|
* limit. It calls write_chunk() in a loop and handles write event timer.
|
||||||
*/
|
*/
|
||||||
nxt_work_handler_t write;
|
nxt_work_handler_t write;
|
||||||
|
|
||||||
@@ -175,7 +175,7 @@ typedef struct {
|
|||||||
nxt_task_t task;
|
nxt_task_t task;
|
||||||
|
|
||||||
uint32_t ready;
|
uint32_t ready;
|
||||||
uint32_t batch0;
|
uint32_t batch;
|
||||||
|
|
||||||
/* An accept() interface is cached to minimize memory accesses. */
|
/* An accept() interface is cached to minimize memory accesses. */
|
||||||
nxt_work_handler_t accept;
|
nxt_work_handler_t accept;
|
||||||
@@ -299,13 +299,13 @@ NXT_EXPORT void nxt_event_conn_job_sendfile(nxt_task_t *task,
|
|||||||
c->socket.task, c, c->socket.data)
|
c->socket.task, c, c->socket.data)
|
||||||
|
|
||||||
|
|
||||||
#define nxt_event_conn_read(e, c) \
|
#define nxt_event_conn_read(engine, c) \
|
||||||
do { \
|
do { \
|
||||||
nxt_event_engine_t *engine = e; \
|
nxt_event_engine_t *e = engine; \
|
||||||
\
|
\
|
||||||
c->socket.read_work_queue = &engine->read_work_queue; \
|
c->socket.read_work_queue = &e->read_work_queue; \
|
||||||
\
|
\
|
||||||
nxt_work_queue_add(&engine->read_work_queue, c->io->read, \
|
nxt_work_queue_add(&e->read_work_queue, c->io->read, \
|
||||||
c->socket.task, c, c->socket.data); \
|
c->socket.task, c, c->socket.data); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ nxt_event_conn_listen(nxt_task_t *task, nxt_listen_socket_t *ls)
|
|||||||
cls->socket.fd = ls->socket;
|
cls->socket.fd = ls->socket;
|
||||||
|
|
||||||
engine = task->thread->engine;
|
engine = task->thread->engine;
|
||||||
cls->batch0 = engine->batch0;
|
cls->batch = engine->batch;
|
||||||
|
|
||||||
cls->socket.read_work_queue = &engine->accept_work_queue;
|
cls->socket.read_work_queue = &engine->accept_work_queue;
|
||||||
cls->socket.read_handler = nxt_event_conn_listen_handler;
|
cls->socket.read_handler = nxt_event_conn_listen_handler;
|
||||||
@@ -130,7 +130,7 @@ nxt_event_conn_listen_handler(nxt_task_t *task, void *obj, void *data)
|
|||||||
nxt_event_conn_listen_t *cls;
|
nxt_event_conn_listen_t *cls;
|
||||||
|
|
||||||
cls = obj;
|
cls = obj;
|
||||||
cls->ready = cls->batch0;
|
cls->ready = cls->batch;
|
||||||
|
|
||||||
cls->accept(task, cls, data);
|
cls->accept(task, cls, data);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -182,7 +182,7 @@ nxt_event_conn_job_sendfile_return(nxt_task_t *task, void *obj, void *data)
|
|||||||
b = jbs->out;
|
b = jbs->out;
|
||||||
|
|
||||||
/* The job must be destroyed before connection error handler. */
|
/* The job must be destroyed before connection error handler. */
|
||||||
nxt_job_destroy(jbs);
|
nxt_job_destroy(task, jbs);
|
||||||
|
|
||||||
if (c->write_state->process_buffers) {
|
if (c->write_state->process_buffers) {
|
||||||
b = nxt_event_conn_job_sendfile_completion(task, c, b);
|
b = nxt_event_conn_job_sendfile_completion(task, c, b);
|
||||||
|
|||||||
@@ -25,11 +25,12 @@ static nxt_work_handler_t nxt_event_engine_queue_pop(nxt_event_engine_t *engine,
|
|||||||
|
|
||||||
|
|
||||||
nxt_event_engine_t *
|
nxt_event_engine_t *
|
||||||
nxt_event_engine_create(nxt_thread_t *thr,
|
nxt_event_engine_create(nxt_task_t *task,
|
||||||
const nxt_event_interface_t *interface, const nxt_sig_event_t *signals,
|
const nxt_event_interface_t *interface, const nxt_sig_event_t *signals,
|
||||||
nxt_uint_t flags, nxt_uint_t batch)
|
nxt_uint_t flags, nxt_uint_t batch)
|
||||||
{
|
{
|
||||||
nxt_uint_t events;
|
nxt_uint_t events;
|
||||||
|
nxt_thread_t *thread;
|
||||||
nxt_event_engine_t *engine;
|
nxt_event_engine_t *engine;
|
||||||
|
|
||||||
engine = nxt_zalloc(sizeof(nxt_event_engine_t));
|
engine = nxt_zalloc(sizeof(nxt_event_engine_t));
|
||||||
@@ -37,14 +38,16 @@ nxt_event_engine_create(nxt_thread_t *thr,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
engine->task.thread = thr;
|
thread = task->thread;
|
||||||
engine->task.log = thr->log;
|
|
||||||
|
engine->task.thread = thread;
|
||||||
|
engine->task.log = thread->log;
|
||||||
engine->task.ident = nxt_task_next_ident();
|
engine->task.ident = nxt_task_next_ident();
|
||||||
|
|
||||||
thr->engine = engine;
|
thread->engine = engine;
|
||||||
thr->fiber = &engine->fibers->fiber;
|
thread->fiber = &engine->fibers->fiber;
|
||||||
|
|
||||||
engine->batch0 = batch;
|
engine->batch = batch;
|
||||||
|
|
||||||
if (flags & NXT_ENGINE_FIBERS) {
|
if (flags & NXT_ENGINE_FIBERS) {
|
||||||
engine->fibers = nxt_fiber_main_create(engine);
|
engine->fibers = nxt_fiber_main_create(engine);
|
||||||
@@ -111,8 +114,10 @@ nxt_event_engine_create(nxt_thread_t *thr,
|
|||||||
goto timers_fail;
|
goto timers_fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
nxt_thread_time_update(thr);
|
thread = task->thread;
|
||||||
engine->timers.now = nxt_thread_monotonic_time(thr) / 1000000;
|
|
||||||
|
nxt_thread_time_update(thread);
|
||||||
|
engine->timers.now = nxt_thread_monotonic_time(thread) / 1000000;
|
||||||
|
|
||||||
engine->max_connections = 0xffffffff;
|
engine->max_connections = 0xffffffff;
|
||||||
|
|
||||||
@@ -122,7 +127,7 @@ nxt_event_engine_create(nxt_thread_t *thr,
|
|||||||
#if !(NXT_THREADS)
|
#if !(NXT_THREADS)
|
||||||
|
|
||||||
if (interface->signal_support) {
|
if (interface->signal_support) {
|
||||||
thr->time.signal = -1;
|
thread->time.signal = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -368,14 +373,12 @@ nxt_event_engine_signal_handler(nxt_task_t *task, void *obj, void *data)
|
|||||||
|
|
||||||
|
|
||||||
nxt_int_t
|
nxt_int_t
|
||||||
nxt_event_engine_change(nxt_thread_t *thr, nxt_task_t *task,
|
nxt_event_engine_change(nxt_event_engine_t *engine,
|
||||||
const nxt_event_interface_t *interface, nxt_uint_t batch)
|
const nxt_event_interface_t *interface, nxt_uint_t batch)
|
||||||
{
|
{
|
||||||
nxt_uint_t events;
|
nxt_uint_t events;
|
||||||
nxt_event_engine_t *engine;
|
|
||||||
|
|
||||||
engine = thr->engine;
|
engine->batch = batch;
|
||||||
engine->batch0 = batch;
|
|
||||||
|
|
||||||
if (!engine->event.signal_support && interface->signal_support) {
|
if (!engine->event.signal_support && interface->signal_support) {
|
||||||
/*
|
/*
|
||||||
@@ -388,7 +391,7 @@ nxt_event_engine_change(nxt_thread_t *thr, nxt_task_t *task,
|
|||||||
* Add to engine fast work queue the signal events possibly
|
* Add to engine fast work queue the signal events possibly
|
||||||
* received before the blocking signal processing.
|
* received before the blocking signal processing.
|
||||||
*/
|
*/
|
||||||
nxt_event_engine_signal_pipe(task, &engine->pipe->event, NULL);
|
nxt_event_engine_signal_pipe(&engine->task, &engine->pipe->event, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (engine->pipe != NULL && interface->enable_post != NULL) {
|
if (engine->pipe != NULL && interface->enable_post != NULL) {
|
||||||
|
|||||||
@@ -477,7 +477,7 @@ struct nxt_event_engine_s {
|
|||||||
|
|
||||||
uint8_t shutdown; /* 1 bit */
|
uint8_t shutdown; /* 1 bit */
|
||||||
|
|
||||||
uint32_t batch0;
|
uint32_t batch;
|
||||||
uint32_t connections;
|
uint32_t connections;
|
||||||
uint32_t max_connections;
|
uint32_t max_connections;
|
||||||
|
|
||||||
@@ -486,11 +486,11 @@ struct nxt_event_engine_s {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
NXT_EXPORT nxt_event_engine_t *nxt_event_engine_create(nxt_thread_t *thr,
|
NXT_EXPORT nxt_event_engine_t *nxt_event_engine_create(nxt_task_t *task,
|
||||||
const nxt_event_interface_t *interface, const nxt_sig_event_t *signals,
|
const nxt_event_interface_t *interface, const nxt_sig_event_t *signals,
|
||||||
nxt_uint_t flags, nxt_uint_t batch);
|
nxt_uint_t flags, nxt_uint_t batch);
|
||||||
NXT_EXPORT nxt_int_t nxt_event_engine_change(nxt_thread_t *thr,
|
NXT_EXPORT nxt_int_t nxt_event_engine_change(nxt_event_engine_t *engine,
|
||||||
nxt_task_t *task, const nxt_event_interface_t *interface, nxt_uint_t batch);
|
const nxt_event_interface_t *interface, nxt_uint_t batch);
|
||||||
NXT_EXPORT void nxt_event_engine_free(nxt_event_engine_t *engine);
|
NXT_EXPORT void nxt_event_engine_free(nxt_event_engine_t *engine);
|
||||||
NXT_EXPORT void nxt_event_engine_start(nxt_event_engine_t *engine);
|
NXT_EXPORT void nxt_event_engine_start(nxt_event_engine_t *engine);
|
||||||
|
|
||||||
|
|||||||
@@ -8,11 +8,9 @@
|
|||||||
|
|
||||||
|
|
||||||
nxt_int_t
|
nxt_int_t
|
||||||
nxt_file_open(nxt_file_t *file, nxt_uint_t mode, nxt_uint_t create,
|
nxt_file_open(nxt_task_t *task, nxt_file_t *file, nxt_uint_t mode,
|
||||||
nxt_file_access_t access)
|
nxt_uint_t create, nxt_file_access_t access)
|
||||||
{
|
{
|
||||||
nxt_thread_debug(thr);
|
|
||||||
|
|
||||||
#ifdef __CYGWIN__
|
#ifdef __CYGWIN__
|
||||||
mode |= O_BINARY;
|
mode |= O_BINARY;
|
||||||
#endif
|
#endif
|
||||||
@@ -24,18 +22,20 @@ nxt_file_open(nxt_file_t *file, nxt_uint_t mode, nxt_uint_t create,
|
|||||||
|
|
||||||
file->error = (file->fd == -1) ? nxt_errno : 0;
|
file->error = (file->fd == -1) ? nxt_errno : 0;
|
||||||
|
|
||||||
nxt_thread_time_debug_update(thr);
|
#if (NXT_DEBUG)
|
||||||
|
nxt_thread_time_update(task->thread);
|
||||||
|
#endif
|
||||||
|
|
||||||
nxt_log_debug(thr->log, "open(\"%FN\", 0x%uXi, 0x%uXi): %FD err:%d",
|
nxt_debug(task, "open(\"%FN\", 0x%uXi, 0x%uXi): %FD err:%d",
|
||||||
file->name, mode, access, file->fd, file->error);
|
file->name, mode, access, file->fd, file->error);
|
||||||
|
|
||||||
if (file->fd != -1) {
|
if (file->fd != -1) {
|
||||||
return NXT_OK;
|
return NXT_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (file->log_level != 0) {
|
if (file->log_level != 0) {
|
||||||
nxt_thread_log_error(file->log_level, "open(\"%FN\") failed %E",
|
nxt_log(task, file->log_level, "open(\"%FN\") failed %E",
|
||||||
file->name, file->error);
|
file->name, file->error);
|
||||||
}
|
}
|
||||||
|
|
||||||
return NXT_ERROR;
|
return NXT_ERROR;
|
||||||
@@ -43,13 +43,13 @@ nxt_file_open(nxt_file_t *file, nxt_uint_t mode, nxt_uint_t create,
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
nxt_file_close(nxt_file_t *file)
|
nxt_file_close(nxt_task_t *task, nxt_file_t *file)
|
||||||
{
|
{
|
||||||
nxt_thread_log_debug("close(%FD)", file->fd);
|
nxt_debug(task, "close(%FD)", file->fd);
|
||||||
|
|
||||||
if (close(file->fd) != 0) {
|
if (close(file->fd) != 0) {
|
||||||
nxt_thread_log_error(NXT_LOG_CRIT, "close(%FD, \"%FN\") failed %E",
|
nxt_log(task, NXT_LOG_CRIT, "close(%FD, \"%FN\") failed %E",
|
||||||
file->fd, file->name, nxt_errno);
|
file->fd, file->name, nxt_errno);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -106,10 +106,8 @@ typedef struct {
|
|||||||
} nxt_file_t;
|
} nxt_file_t;
|
||||||
|
|
||||||
|
|
||||||
NXT_EXPORT nxt_int_t nxt_file_open(nxt_file_t *file, nxt_uint_t mode,
|
NXT_EXPORT nxt_int_t nxt_file_open(nxt_task_t *task, nxt_file_t *file,
|
||||||
nxt_uint_t create, nxt_file_access_t access);
|
nxt_uint_t mode, nxt_uint_t create, nxt_file_access_t access);
|
||||||
|
|
||||||
#define nxt_file_open_n "open"
|
|
||||||
|
|
||||||
|
|
||||||
/* The file open access modes. */
|
/* The file open access modes. */
|
||||||
@@ -128,7 +126,7 @@ NXT_EXPORT nxt_int_t nxt_file_open(nxt_file_t *file, nxt_uint_t mode,
|
|||||||
#define NXT_FILE_OWNER_ACCESS 0600
|
#define NXT_FILE_OWNER_ACCESS 0600
|
||||||
|
|
||||||
|
|
||||||
NXT_EXPORT void nxt_file_close(nxt_file_t *file);
|
NXT_EXPORT void nxt_file_close(nxt_task_t *task, nxt_file_t *file);
|
||||||
NXT_EXPORT ssize_t nxt_file_write(nxt_file_t *file, const u_char *buf,
|
NXT_EXPORT ssize_t nxt_file_write(nxt_file_t *file, const u_char *buf,
|
||||||
size_t size, nxt_off_t offset);
|
size_t size, nxt_off_t offset);
|
||||||
NXT_EXPORT ssize_t nxt_file_read(nxt_file_t *file, u_char *buf, size_t size,
|
NXT_EXPORT ssize_t nxt_file_read(nxt_file_t *file, u_char *buf, size_t size,
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ nxt_job_init(nxt_job_t *job, size_t size)
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
nxt_job_destroy(void *data)
|
nxt_job_destroy(nxt_task_t *task, void *data)
|
||||||
{
|
{
|
||||||
nxt_job_t *job;
|
nxt_job_t *job;
|
||||||
|
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ typedef struct {
|
|||||||
|
|
||||||
NXT_EXPORT void *nxt_job_create(nxt_mem_pool_t *mp, size_t size);
|
NXT_EXPORT void *nxt_job_create(nxt_mem_pool_t *mp, size_t size);
|
||||||
NXT_EXPORT void nxt_job_init(nxt_job_t *job, size_t size);
|
NXT_EXPORT void nxt_job_init(nxt_job_t *job, size_t size);
|
||||||
NXT_EXPORT void nxt_job_destroy(void *data);
|
NXT_EXPORT void nxt_job_destroy(nxt_task_t *task, void *data);
|
||||||
NXT_EXPORT nxt_int_t nxt_job_cleanup_add(nxt_mem_pool_t *mp, nxt_job_t *job);
|
NXT_EXPORT nxt_int_t nxt_job_cleanup_add(nxt_mem_pool_t *mp, nxt_job_t *job);
|
||||||
|
|
||||||
NXT_EXPORT void nxt_job_start(nxt_task_t *task, nxt_job_t *job,
|
NXT_EXPORT void nxt_job_start(nxt_task_t *task, nxt_job_t *job,
|
||||||
|
|||||||
@@ -738,7 +738,7 @@ nxt_kqueue_poll(nxt_event_engine_t *engine, nxt_msec_t timeout)
|
|||||||
ev->kq_errno = err;
|
ev->kq_errno = err;
|
||||||
ev->kq_eof = eof;
|
ev->kq_eof = eof;
|
||||||
|
|
||||||
if (ev->read == NXT_EVENT_BLOCKED) {
|
if (ev->read <= NXT_EVENT_BLOCKED) {
|
||||||
nxt_debug(ev->task, "blocked read event fd:%d", ev->fd);
|
nxt_debug(ev->task, "blocked read event fd:%d", ev->fd);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -769,7 +769,7 @@ nxt_kqueue_poll(nxt_event_engine_t *engine, nxt_msec_t timeout)
|
|||||||
ev->kq_errno = err;
|
ev->kq_errno = err;
|
||||||
ev->kq_eof = eof;
|
ev->kq_eof = eof;
|
||||||
|
|
||||||
if (ev->write == NXT_EVENT_BLOCKED) {
|
if (ev->write <= NXT_EVENT_BLOCKED) {
|
||||||
nxt_debug(ev->task, "blocked write event fd:%d", ev->fd);
|
nxt_debug(ev->task, "blocked write event fd:%d", ev->fd);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -908,7 +908,7 @@ nxt_kqueue_listen_handler(nxt_task_t *task, void *obj, void *data)
|
|||||||
nxt_debug(task, "kevent fd:%d avail:%D",
|
nxt_debug(task, "kevent fd:%d avail:%D",
|
||||||
cls->socket.fd, cls->socket.kq_available);
|
cls->socket.fd, cls->socket.kq_available);
|
||||||
|
|
||||||
cls->ready = nxt_min(cls->batch0, (uint32_t) cls->socket.kq_available);
|
cls->ready = nxt_min(cls->batch, (uint32_t) cls->socket.kq_available);
|
||||||
|
|
||||||
nxt_kqueue_event_conn_io_accept(task, cls, data);
|
nxt_kqueue_event_conn_io_accept(task, cls, data);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ nxt_lib_start(const char *app, char **argv, char ***envp)
|
|||||||
int n;
|
int n;
|
||||||
nxt_int_t flags;
|
nxt_int_t flags;
|
||||||
nxt_bool_t update;
|
nxt_bool_t update;
|
||||||
nxt_thread_t *thr;
|
nxt_thread_t *thread;
|
||||||
|
|
||||||
flags = nxt_stderr_start();
|
flags = nxt_stderr_start();
|
||||||
|
|
||||||
@@ -64,16 +64,15 @@ nxt_lib_start(const char *app, char **argv, char ***envp)
|
|||||||
/* Thread log is required for nxt_malloc() in nxt_strerror_start(). */
|
/* Thread log is required for nxt_malloc() in nxt_strerror_start(). */
|
||||||
|
|
||||||
nxt_thread_init_data(nxt_thread_context);
|
nxt_thread_init_data(nxt_thread_context);
|
||||||
thr = nxt_thread();
|
thread = nxt_thread();
|
||||||
thr->log = &nxt_main_log;
|
thread->log = &nxt_main_log;
|
||||||
|
|
||||||
#if (NXT_THREADS)
|
thread->handle = nxt_thread_handle();
|
||||||
thr->handle = nxt_thread_handle();
|
thread->time.signal = -1;
|
||||||
thr->time.signal = -1;
|
nxt_thread_time_update(thread);
|
||||||
#endif
|
|
||||||
|
|
||||||
nxt_main_task.thread = thr;
|
nxt_main_task.thread = thread;
|
||||||
nxt_main_task.log = thr->log;
|
nxt_main_task.log = thread->log;
|
||||||
nxt_main_task.ident = nxt_task_next_ident();
|
nxt_main_task.ident = nxt_task_next_ident();
|
||||||
|
|
||||||
if (nxt_strerror_start() != NXT_OK) {
|
if (nxt_strerror_start() != NXT_OK) {
|
||||||
@@ -81,7 +80,7 @@ nxt_lib_start(const char *app, char **argv, char ***envp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (flags != -1) {
|
if (flags != -1) {
|
||||||
nxt_log_debug(thr->log, "stderr flags: 0x%04Xd", flags);
|
nxt_debug(&nxt_main_task, "stderr flags: 0x%04Xd", flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _SC_NPROCESSORS_ONLN
|
#ifdef _SC_NPROCESSORS_ONLN
|
||||||
@@ -93,7 +92,7 @@ nxt_lib_start(const char *app, char **argv, char ***envp)
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
nxt_log_debug(thr->log, "ncpu: %ui", n);
|
nxt_debug(&nxt_main_task, "ncpu: %ui", n);
|
||||||
|
|
||||||
if (n > 1) {
|
if (n > 1) {
|
||||||
nxt_ncpu = n;
|
nxt_ncpu = n;
|
||||||
@@ -105,12 +104,12 @@ nxt_lib_start(const char *app, char **argv, char ***envp)
|
|||||||
|
|
||||||
nxt_pagesize = getpagesize();
|
nxt_pagesize = getpagesize();
|
||||||
|
|
||||||
nxt_log_debug(thr->log, "pagesize: %ui", nxt_pagesize);
|
nxt_debug(&nxt_main_task, "pagesize: %ui", nxt_pagesize);
|
||||||
|
|
||||||
if (argv != NULL) {
|
if (argv != NULL) {
|
||||||
update = (argv[0] == app);
|
update = (argv[0] == app);
|
||||||
|
|
||||||
nxt_process_arguments(argv, envp);
|
nxt_process_arguments(&nxt_main_task, argv, envp);
|
||||||
|
|
||||||
if (update) {
|
if (update) {
|
||||||
nxt_log_start(nxt_process_argv[0]);
|
nxt_log_start(nxt_process_argv[0]);
|
||||||
@@ -131,12 +130,12 @@ nxt_lib_stop(void)
|
|||||||
for ( ;; ) {
|
for ( ;; ) {
|
||||||
nxt_thread_pool_t *tp;
|
nxt_thread_pool_t *tp;
|
||||||
|
|
||||||
nxt_thread_spin_lock(&cycle->lock);
|
nxt_thread_spin_lock(&rt->lock);
|
||||||
|
|
||||||
tp = cycle->thread_pools;
|
tp = rt->thread_pools;
|
||||||
cycle->thread_pools = (tp != NULL) ? tp->next : NULL;
|
rt->thread_pools = (tp != NULL) ? tp->next : NULL;
|
||||||
|
|
||||||
nxt_thread_spin_unlock(&cycle->lock);
|
nxt_thread_spin_unlock(&rt->lock);
|
||||||
|
|
||||||
if (tp == NULL) {
|
if (tp == NULL) {
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ nxt_list_elt(nxt_list_t *list, nxt_uint_t n)
|
|||||||
|
|
||||||
#define nxt_list_each(elt, list) \
|
#define nxt_list_each(elt, list) \
|
||||||
do { \
|
do { \
|
||||||
if (nxt_fast_path((list) != NULL)) { \
|
if (nxt_fast_path((list) != NULL)) { \
|
||||||
void *_end; \
|
void *_end; \
|
||||||
nxt_list_part_t *_part = nxt_list_part(list); \
|
nxt_list_part_t *_part = nxt_list_part(list); \
|
||||||
\
|
\
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <nxt_main.h>
|
#include <nxt_main.h>
|
||||||
#include <nxt_cycle.h>
|
#include <nxt_runtime.h>
|
||||||
|
|
||||||
|
|
||||||
extern char **environ;
|
extern char **environ;
|
||||||
@@ -14,8 +14,7 @@ extern char **environ;
|
|||||||
int nxt_cdecl
|
int nxt_cdecl
|
||||||
main(int argc, char **argv)
|
main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
nxt_int_t ret;
|
nxt_int_t ret;
|
||||||
nxt_thread_t *thr;
|
|
||||||
|
|
||||||
if (nxt_lib_start("nginext", argv, &environ) != NXT_OK) {
|
if (nxt_lib_start("nginext", argv, &environ) != NXT_OK) {
|
||||||
return 1;
|
return 1;
|
||||||
@@ -23,20 +22,17 @@ main(int argc, char **argv)
|
|||||||
|
|
||||||
// nxt_main_log.level = NXT_LOG_INFO;
|
// nxt_main_log.level = NXT_LOG_INFO;
|
||||||
|
|
||||||
thr = nxt_thread();
|
|
||||||
nxt_thread_time_update(thr);
|
|
||||||
|
|
||||||
nxt_main_log.handler = nxt_log_time_handler;
|
nxt_main_log.handler = nxt_log_time_handler;
|
||||||
|
|
||||||
nxt_log_error(NXT_LOG_INFO, thr->log, "nginext started");
|
nxt_log(&nxt_main_task, NXT_LOG_INFO, "nginext started");
|
||||||
|
|
||||||
ret = nxt_cycle_create(thr, &nxt_main_task, NULL, NULL);
|
ret = nxt_runtime_create(&nxt_main_task);
|
||||||
|
|
||||||
if (ret != NXT_OK) {
|
if (ret != NXT_OK) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
nxt_event_engine_start(thr->engine);
|
nxt_event_engine_start(nxt_main_task.thread->engine);
|
||||||
|
|
||||||
nxt_unreachable();
|
nxt_unreachable();
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -14,13 +14,22 @@
|
|||||||
#include <nxt_clang.h>
|
#include <nxt_clang.h>
|
||||||
#include <nxt_types.h>
|
#include <nxt_types.h>
|
||||||
#include <nxt_time.h>
|
#include <nxt_time.h>
|
||||||
|
|
||||||
|
typedef struct nxt_mem_pool_s nxt_mem_pool_t;
|
||||||
|
#include <nxt_array.h>
|
||||||
|
|
||||||
|
typedef struct nxt_port_s nxt_port_t;
|
||||||
|
typedef struct nxt_task_s nxt_task_t;
|
||||||
|
typedef struct nxt_port_recv_msg_s nxt_port_recv_msg_t;
|
||||||
|
typedef void (*nxt_port_handler_t)(nxt_task_t *task, nxt_port_recv_msg_t *msg);
|
||||||
|
typedef struct nxt_sig_event_s nxt_sig_event_t;
|
||||||
|
typedef struct nxt_runtime_s nxt_runtime_t;
|
||||||
|
|
||||||
#include <nxt_process.h>
|
#include <nxt_process.h>
|
||||||
|
|
||||||
typedef struct nxt_task_s nxt_task_t;
|
|
||||||
typedef struct nxt_thread_s nxt_thread_t;
|
typedef struct nxt_thread_s nxt_thread_t;
|
||||||
#include <nxt_thread_id.h>
|
#include <nxt_thread_id.h>
|
||||||
|
|
||||||
typedef struct nxt_mem_pool_s nxt_mem_pool_t;
|
|
||||||
#include <nxt_mem_pool.h>
|
#include <nxt_mem_pool.h>
|
||||||
|
|
||||||
#include <nxt_errno.h>
|
#include <nxt_errno.h>
|
||||||
@@ -89,7 +98,6 @@ typedef struct nxt_thread_pool_s nxt_thread_pool_t;
|
|||||||
#include <nxt_hash.h>
|
#include <nxt_hash.h>
|
||||||
|
|
||||||
#include <nxt_sort.h>
|
#include <nxt_sort.h>
|
||||||
#include <nxt_array.h>
|
|
||||||
#include <nxt_vector.h>
|
#include <nxt_vector.h>
|
||||||
#include <nxt_list.h>
|
#include <nxt_list.h>
|
||||||
|
|
||||||
@@ -110,8 +118,7 @@ typedef struct nxt_event_conn_s nxt_event_conn_t;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#define \
|
#define nxt_thread() \
|
||||||
nxt_thread() \
|
|
||||||
(nxt_thread_t *) nxt_thread_get_data(nxt_thread_context)
|
(nxt_thread_t *) nxt_thread_get_data(nxt_thread_context)
|
||||||
|
|
||||||
nxt_thread_extern_data(nxt_thread_t, nxt_thread_context);
|
nxt_thread_extern_data(nxt_thread_t, nxt_thread_context);
|
||||||
@@ -121,7 +128,6 @@ nxt_thread_extern_data(nxt_thread_t, nxt_thread_context);
|
|||||||
|
|
||||||
#include <nxt_fd_event.h>
|
#include <nxt_fd_event.h>
|
||||||
|
|
||||||
typedef struct nxt_cycle_s nxt_cycle_t;
|
|
||||||
#include <nxt_port.h>
|
#include <nxt_port.h>
|
||||||
#if (NXT_THREADS)
|
#if (NXT_THREADS)
|
||||||
#include <nxt_thread_pool.h>
|
#include <nxt_thread_pool.h>
|
||||||
@@ -154,7 +160,7 @@ typedef struct nxt_upstream_source_s nxt_upstream_source_t;
|
|||||||
#include <nxt_upstream_source.h>
|
#include <nxt_upstream_source.h>
|
||||||
#include <nxt_http_source.h>
|
#include <nxt_http_source.h>
|
||||||
#include <nxt_fastcgi_source.h>
|
#include <nxt_fastcgi_source.h>
|
||||||
#include <nxt_cycle.h>
|
#include <nxt_runtime.h>
|
||||||
|
|
||||||
|
|
||||||
#if (NXT_LIB_UNIT_TEST)
|
#if (NXT_LIB_UNIT_TEST)
|
||||||
|
|||||||
@@ -5,46 +5,39 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <nxt_main.h>
|
#include <nxt_main.h>
|
||||||
#include <nxt_cycle.h>
|
#include <nxt_runtime.h>
|
||||||
#include <nxt_port.h>
|
#include <nxt_port.h>
|
||||||
#include <nxt_master_process.h>
|
#include <nxt_master_process.h>
|
||||||
|
|
||||||
|
|
||||||
static nxt_int_t nxt_master_process_port_create(nxt_task_t *task,
|
static nxt_int_t nxt_master_process_port_create(nxt_task_t *task,
|
||||||
nxt_cycle_t *cycle);
|
nxt_runtime_t *rt);
|
||||||
static void nxt_master_process_title(void);
|
static void nxt_master_process_title(nxt_task_t *task);
|
||||||
|
static nxt_int_t nxt_master_start_controller_process(nxt_task_t *task,
|
||||||
|
nxt_runtime_t *rt);
|
||||||
|
static nxt_int_t nxt_master_start_router_process(nxt_task_t *task,
|
||||||
|
nxt_runtime_t *rt);
|
||||||
static nxt_int_t nxt_master_start_worker_processes(nxt_task_t *task,
|
static nxt_int_t nxt_master_start_worker_processes(nxt_task_t *task,
|
||||||
nxt_cycle_t *cycle);
|
nxt_runtime_t *rt);
|
||||||
static nxt_int_t nxt_master_create_worker_process(nxt_task_t *task,
|
static nxt_int_t nxt_master_create_worker_process(nxt_task_t *task,
|
||||||
nxt_cycle_t *cycle);
|
nxt_runtime_t *rt, nxt_process_init_t *init);
|
||||||
static void nxt_master_stop_previous_worker_processes(nxt_task_t *task,
|
|
||||||
void *obj, void *data);
|
|
||||||
static void nxt_master_process_sighup_handler(nxt_task_t *task, void *obj,
|
|
||||||
void *data);
|
|
||||||
static void nxt_master_process_new_cycle(nxt_task_t *task, nxt_cycle_t *cycle);
|
|
||||||
static void nxt_master_process_sigterm_handler(nxt_task_t *task, void *obj,
|
static void nxt_master_process_sigterm_handler(nxt_task_t *task, void *obj,
|
||||||
void *data);
|
void *data);
|
||||||
static void nxt_master_process_sigquit_handler(nxt_task_t *task, void *obj,
|
static void nxt_master_process_sigquit_handler(nxt_task_t *task, void *obj,
|
||||||
void *data);
|
void *data);
|
||||||
static void nxt_master_process_sigusr1_handler(nxt_task_t *task, void *obj,
|
static void nxt_master_process_sigusr1_handler(nxt_task_t *task, void *obj,
|
||||||
void *data);
|
void *data);
|
||||||
static void nxt_master_process_sigusr2_handler(nxt_task_t *task, void *obj,
|
|
||||||
void *data);
|
|
||||||
static char **nxt_master_process_upgrade_environment(nxt_cycle_t *cycle);
|
|
||||||
static char **nxt_master_process_upgrade_environment_create(nxt_cycle_t *cycle);
|
|
||||||
static void nxt_master_process_sigchld_handler(nxt_task_t *task, void *obj,
|
static void nxt_master_process_sigchld_handler(nxt_task_t *task, void *obj,
|
||||||
void *data);
|
void *data);
|
||||||
static void nxt_master_cleanup_worker_process(nxt_task_t *task, nxt_pid_t pid);
|
static void nxt_master_cleanup_worker_process(nxt_task_t *task, nxt_pid_t pid);
|
||||||
|
|
||||||
|
|
||||||
const nxt_sig_event_t nxt_master_process_signals[] = {
|
const nxt_sig_event_t nxt_master_process_signals[] = {
|
||||||
nxt_event_signal(SIGHUP, nxt_master_process_sighup_handler),
|
|
||||||
nxt_event_signal(SIGINT, nxt_master_process_sigterm_handler),
|
nxt_event_signal(SIGINT, nxt_master_process_sigterm_handler),
|
||||||
nxt_event_signal(SIGQUIT, nxt_master_process_sigquit_handler),
|
nxt_event_signal(SIGQUIT, nxt_master_process_sigquit_handler),
|
||||||
nxt_event_signal(SIGTERM, nxt_master_process_sigterm_handler),
|
nxt_event_signal(SIGTERM, nxt_master_process_sigterm_handler),
|
||||||
nxt_event_signal(SIGCHLD, nxt_master_process_sigchld_handler),
|
nxt_event_signal(SIGCHLD, nxt_master_process_sigchld_handler),
|
||||||
nxt_event_signal(SIGUSR1, nxt_master_process_sigusr1_handler),
|
nxt_event_signal(SIGUSR1, nxt_master_process_sigusr1_handler),
|
||||||
nxt_event_signal(SIGUSR2, nxt_master_process_sigusr2_handler),
|
|
||||||
nxt_event_signal_end,
|
nxt_event_signal_end,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -54,27 +47,47 @@ static nxt_bool_t nxt_exiting;
|
|||||||
|
|
||||||
nxt_int_t
|
nxt_int_t
|
||||||
nxt_master_process_start(nxt_thread_t *thr, nxt_task_t *task,
|
nxt_master_process_start(nxt_thread_t *thr, nxt_task_t *task,
|
||||||
nxt_cycle_t *cycle)
|
nxt_runtime_t *rt)
|
||||||
{
|
{
|
||||||
cycle->type = NXT_PROCESS_MASTER;
|
nxt_int_t ret;
|
||||||
|
|
||||||
if (nxt_master_process_port_create(task, cycle) != NXT_OK) {
|
rt->type = NXT_PROCESS_MASTER;
|
||||||
|
|
||||||
|
if (nxt_master_process_port_create(task, rt) != NXT_OK) {
|
||||||
return NXT_ERROR;
|
return NXT_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
nxt_master_process_title();
|
nxt_master_process_title(task);
|
||||||
|
|
||||||
return nxt_master_start_worker_processes(task, cycle);
|
ret = nxt_master_start_controller_process(task, rt);
|
||||||
|
if (ret != NXT_OK) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = nxt_master_start_router_process(task, rt);
|
||||||
|
if (ret != NXT_OK) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return nxt_master_start_worker_processes(task, rt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static nxt_int_t
|
static nxt_int_t
|
||||||
nxt_master_process_port_create(nxt_task_t *task, nxt_cycle_t *cycle)
|
nxt_master_process_port_create(nxt_task_t *task, nxt_runtime_t *rt)
|
||||||
{
|
{
|
||||||
nxt_int_t ret;
|
nxt_int_t ret;
|
||||||
nxt_port_t *port;
|
nxt_port_t *port;
|
||||||
|
nxt_process_t *process;
|
||||||
|
|
||||||
port = nxt_array_zero_add(cycle->ports);
|
process = nxt_runtime_new_process(rt);
|
||||||
|
if (nxt_slow_path(process == NULL)) {
|
||||||
|
return NXT_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
process->pid = nxt_pid;
|
||||||
|
|
||||||
|
port = nxt_array_zero_add(process->ports);
|
||||||
if (nxt_slow_path(port == NULL)) {
|
if (nxt_slow_path(port == NULL)) {
|
||||||
return NXT_ERROR;
|
return NXT_ERROR;
|
||||||
}
|
}
|
||||||
@@ -98,7 +111,7 @@ nxt_master_process_port_create(nxt_task_t *task, nxt_cycle_t *cycle)
|
|||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
nxt_master_process_title(void)
|
nxt_master_process_title(nxt_task_t *task)
|
||||||
{
|
{
|
||||||
u_char *p, *end;
|
u_char *p, *end;
|
||||||
nxt_uint_t i;
|
nxt_uint_t i;
|
||||||
@@ -115,22 +128,75 @@ nxt_master_process_title(void)
|
|||||||
|
|
||||||
*p = '\0';
|
*p = '\0';
|
||||||
|
|
||||||
nxt_process_title((char *) title);
|
nxt_process_title(task, (char *) title);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static nxt_int_t
|
static nxt_int_t
|
||||||
nxt_master_start_worker_processes(nxt_task_t *task, nxt_cycle_t *cycle)
|
nxt_master_start_controller_process(nxt_task_t *task, nxt_runtime_t *rt)
|
||||||
{
|
{
|
||||||
nxt_int_t ret;
|
nxt_process_init_t *init;
|
||||||
nxt_uint_t n;
|
|
||||||
|
|
||||||
cycle->process_generation++;
|
init = nxt_mem_alloc(rt->mem_pool, sizeof(nxt_process_init_t));
|
||||||
|
if (nxt_slow_path(init == NULL)) {
|
||||||
|
return NXT_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
n = cycle->worker_processes;
|
init->start = nxt_controller_start;
|
||||||
|
init->name = "controller process";
|
||||||
|
init->user_cred = &rt->user_cred;
|
||||||
|
init->port_handlers = nxt_worker_process_port_handlers;
|
||||||
|
init->signals = nxt_worker_process_signals;
|
||||||
|
init->type = NXT_PROCESS_CONTROLLER;
|
||||||
|
|
||||||
|
return nxt_master_create_worker_process(task, rt, init);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static nxt_int_t
|
||||||
|
nxt_master_start_router_process(nxt_task_t *task, nxt_runtime_t *rt)
|
||||||
|
{
|
||||||
|
nxt_process_init_t *init;
|
||||||
|
|
||||||
|
init = nxt_mem_alloc(rt->mem_pool, sizeof(nxt_process_init_t));
|
||||||
|
if (nxt_slow_path(init == NULL)) {
|
||||||
|
return NXT_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
init->start = nxt_router_start;
|
||||||
|
init->name = "router process";
|
||||||
|
init->user_cred = &rt->user_cred;
|
||||||
|
init->port_handlers = nxt_worker_process_port_handlers;
|
||||||
|
init->signals = nxt_worker_process_signals;
|
||||||
|
init->type = NXT_PROCESS_ROUTER;
|
||||||
|
|
||||||
|
return nxt_master_create_worker_process(task, rt, init);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static nxt_int_t
|
||||||
|
nxt_master_start_worker_processes(nxt_task_t *task, nxt_runtime_t *rt)
|
||||||
|
{
|
||||||
|
nxt_int_t ret;
|
||||||
|
nxt_uint_t n;
|
||||||
|
nxt_process_init_t *init;
|
||||||
|
|
||||||
|
init = nxt_mem_alloc(rt->mem_pool, sizeof(nxt_process_init_t));
|
||||||
|
if (nxt_slow_path(init == NULL)) {
|
||||||
|
return NXT_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
init->start = nxt_app_start;
|
||||||
|
init->name = "worker process";
|
||||||
|
init->user_cred = &rt->user_cred;
|
||||||
|
init->port_handlers = nxt_worker_process_port_handlers;
|
||||||
|
init->signals = nxt_worker_process_signals;
|
||||||
|
init->type = NXT_PROCESS_WORKER;
|
||||||
|
|
||||||
|
n = rt->worker_processes;
|
||||||
|
|
||||||
while (n-- != 0) {
|
while (n-- != 0) {
|
||||||
ret = nxt_master_create_worker_process(task, cycle);
|
ret = nxt_master_create_worker_process(task, rt, init);
|
||||||
|
|
||||||
if (ret != NXT_OK) {
|
if (ret != NXT_OK) {
|
||||||
return ret;
|
return ret;
|
||||||
@@ -142,18 +208,34 @@ nxt_master_start_worker_processes(nxt_task_t *task, nxt_cycle_t *cycle)
|
|||||||
|
|
||||||
|
|
||||||
static nxt_int_t
|
static nxt_int_t
|
||||||
nxt_master_create_worker_process(nxt_task_t *task, nxt_cycle_t *cycle)
|
nxt_master_create_worker_process(nxt_task_t *task, nxt_runtime_t *rt,
|
||||||
|
nxt_process_init_t *init)
|
||||||
{
|
{
|
||||||
nxt_int_t ret;
|
nxt_int_t ret;
|
||||||
nxt_pid_t pid;
|
nxt_pid_t pid;
|
||||||
nxt_port_t *port;
|
nxt_port_t *port;
|
||||||
|
nxt_process_t *process, *master_process;
|
||||||
|
|
||||||
port = nxt_array_zero_add(cycle->ports);
|
/*
|
||||||
|
* TODO: remove process, init, ports from array on memory and fork failures.
|
||||||
|
*/
|
||||||
|
|
||||||
|
process = nxt_runtime_new_process(rt);
|
||||||
|
if (nxt_slow_path(process == NULL)) {
|
||||||
|
return NXT_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
process->init = init;
|
||||||
|
|
||||||
|
master_process = rt->processes->elts;
|
||||||
|
init->master_port = master_process->ports->elts;
|
||||||
|
|
||||||
|
port = nxt_array_zero_add(process->ports);
|
||||||
if (nxt_slow_path(port == NULL)) {
|
if (nxt_slow_path(port == NULL)) {
|
||||||
return NXT_ERROR;
|
return NXT_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
cycle->current_process = cycle->ports->nelts - 1;
|
init->port = port;
|
||||||
|
|
||||||
ret = nxt_port_socket_init(task, port, 0);
|
ret = nxt_port_socket_init(task, port, 0);
|
||||||
if (nxt_slow_path(ret != NXT_OK)) {
|
if (nxt_slow_path(ret != NXT_OK)) {
|
||||||
@@ -161,10 +243,8 @@ nxt_master_create_worker_process(nxt_task_t *task, nxt_cycle_t *cycle)
|
|||||||
}
|
}
|
||||||
|
|
||||||
port->engine = 0;
|
port->engine = 0;
|
||||||
port->generation = cycle->process_generation;
|
|
||||||
|
|
||||||
pid = nxt_process_create(nxt_worker_process_start, cycle,
|
pid = nxt_process_create(task, init);
|
||||||
"start worker process");
|
|
||||||
|
|
||||||
switch (pid) {
|
switch (pid) {
|
||||||
|
|
||||||
@@ -177,110 +257,42 @@ nxt_master_create_worker_process(nxt_task_t *task, nxt_cycle_t *cycle)
|
|||||||
|
|
||||||
default:
|
default:
|
||||||
/* The master process created a new process. */
|
/* The master process created a new process. */
|
||||||
|
process->pid = pid;
|
||||||
port->pid = pid;
|
port->pid = pid;
|
||||||
|
|
||||||
nxt_port_read_close(port);
|
nxt_port_read_close(port);
|
||||||
nxt_port_write_enable(task, port);
|
nxt_port_write_enable(task, port);
|
||||||
|
|
||||||
nxt_port_send_new_port(task, cycle, port);
|
nxt_port_send_new_port(task, rt, port);
|
||||||
return NXT_OK;
|
return NXT_OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
void
|
||||||
nxt_master_process_sighup_handler(nxt_task_t *task, void *obj, void *data)
|
nxt_master_stop_worker_processes(nxt_task_t *task, nxt_runtime_t *rt)
|
||||||
{
|
{
|
||||||
nxt_cycle_t *cycle;
|
nxt_uint_t i, n, nprocesses, nports;
|
||||||
|
nxt_port_t *port;
|
||||||
|
nxt_process_t *process;
|
||||||
|
|
||||||
cycle = nxt_thread_cycle();
|
process = rt->processes->elts;
|
||||||
|
nprocesses = rt->processes->nelts;
|
||||||
|
|
||||||
nxt_log(task, NXT_LOG_NOTICE, "signal %d (%s) recevied, %s",
|
for (i = 0; i < nprocesses; i++) {
|
||||||
(int) (uintptr_t) obj, data,
|
|
||||||
cycle->reconfiguring ? "ignored" : "reconfiguring");
|
|
||||||
|
|
||||||
if (!cycle->reconfiguring) {
|
if (nxt_pid != process[i].pid) {
|
||||||
(void) nxt_cycle_create(task->thread, task, cycle,
|
process[i].init = NULL;
|
||||||
nxt_master_process_new_cycle);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
port = process[i].ports->elts;
|
||||||
|
nports = process[i].ports->nelts;
|
||||||
|
|
||||||
static void
|
for (n = 0; n < nports; n++) {
|
||||||
nxt_master_process_new_cycle(nxt_task_t *task, nxt_cycle_t *cycle)
|
(void) nxt_port_socket_write(task, &port[n], NXT_PORT_MSG_QUIT,
|
||||||
{
|
-1, 0, NULL);
|
||||||
nxt_thread_t *thr;
|
}
|
||||||
|
|
||||||
thr = task->thread;
|
|
||||||
|
|
||||||
nxt_debug(task, "new cycle");
|
|
||||||
|
|
||||||
/* A safe place to free the previous cycle. */
|
|
||||||
nxt_mem_pool_destroy(cycle->previous->mem_pool);
|
|
||||||
|
|
||||||
switch (nxt_master_start_worker_processes(task, cycle)) {
|
|
||||||
|
|
||||||
case NXT_OK:
|
|
||||||
/*
|
|
||||||
* The master process, allow old worker processes to accept new
|
|
||||||
* connections yet 500ms in parallel with new worker processes.
|
|
||||||
*/
|
|
||||||
cycle->timer.handler = nxt_master_stop_previous_worker_processes;
|
|
||||||
cycle->timer.log = &nxt_main_log;
|
|
||||||
|
|
||||||
cycle->timer.work_queue = &thr->engine->fast_work_queue;
|
|
||||||
|
|
||||||
nxt_timer_add(thr->engine, &cycle->timer, 500);
|
|
||||||
|
|
||||||
return;
|
|
||||||
|
|
||||||
case NXT_ERROR:
|
|
||||||
/*
|
|
||||||
* The master process, one or more new worker processes
|
|
||||||
* could not be created, there is no fallback.
|
|
||||||
*/
|
|
||||||
return;
|
|
||||||
|
|
||||||
default: /* NXT_AGAIN */
|
|
||||||
/* A worker process, return to the event engine work queue loop. */
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
|
||||||
nxt_master_stop_previous_worker_processes(nxt_task_t *task, void *obj,
|
|
||||||
void *data)
|
|
||||||
{
|
|
||||||
uint32_t generation;
|
|
||||||
nxt_uint_t i, n;
|
|
||||||
nxt_port_t *port;
|
|
||||||
nxt_cycle_t *cycle;
|
|
||||||
|
|
||||||
cycle = nxt_thread_cycle();
|
|
||||||
|
|
||||||
port = cycle->ports->elts;
|
|
||||||
n = cycle->ports->nelts;
|
|
||||||
|
|
||||||
generation = cycle->process_generation - 1;
|
|
||||||
|
|
||||||
/* The port[0] is the master process port. */
|
|
||||||
|
|
||||||
for (i = 1; i < n; i++) {
|
|
||||||
if (port[i].generation == generation) {
|
|
||||||
(void) nxt_port_socket_write(task, &port[i],
|
|
||||||
NXT_PORT_MSG_QUIT, -1, 0, NULL);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cycle->reconfiguring = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
nxt_master_stop_worker_processes(nxt_task_t *task, nxt_cycle_t *cycle)
|
|
||||||
{
|
|
||||||
nxt_port_write(task, cycle, NXT_PORT_MSG_QUIT, -1, 0, NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -295,7 +307,7 @@ nxt_master_process_sigterm_handler(nxt_task_t *task, void *obj, void *data)
|
|||||||
|
|
||||||
nxt_exiting = 1;
|
nxt_exiting = 1;
|
||||||
|
|
||||||
nxt_cycle_quit(task, NULL);
|
nxt_runtime_quit(task);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -309,7 +321,7 @@ nxt_master_process_sigquit_handler(nxt_task_t *task, void *obj, void *data)
|
|||||||
|
|
||||||
nxt_exiting = 1;
|
nxt_exiting = 1;
|
||||||
|
|
||||||
nxt_cycle_quit(task, NULL);
|
nxt_runtime_quit(task);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -319,7 +331,7 @@ nxt_master_process_sigusr1_handler(nxt_task_t *task, void *obj, void *data)
|
|||||||
nxt_int_t ret;
|
nxt_int_t ret;
|
||||||
nxt_uint_t n;
|
nxt_uint_t n;
|
||||||
nxt_file_t *file, *new_file;
|
nxt_file_t *file, *new_file;
|
||||||
nxt_cycle_t *cycle;
|
nxt_runtime_t *rt;
|
||||||
nxt_array_t *new_files;
|
nxt_array_t *new_files;
|
||||||
nxt_mem_pool_t *mp;
|
nxt_mem_pool_t *mp;
|
||||||
|
|
||||||
@@ -331,9 +343,9 @@ nxt_master_process_sigusr1_handler(nxt_task_t *task, void *obj, void *data)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
cycle = nxt_thread_cycle();
|
rt = task->thread->runtime;
|
||||||
|
|
||||||
n = nxt_list_nelts(cycle->log_files);
|
n = nxt_list_nelts(rt->log_files);
|
||||||
|
|
||||||
new_files = nxt_array_create(mp, n, sizeof(nxt_file_t));
|
new_files = nxt_array_create(mp, n, sizeof(nxt_file_t));
|
||||||
if (new_files == NULL) {
|
if (new_files == NULL) {
|
||||||
@@ -341,7 +353,7 @@ nxt_master_process_sigusr1_handler(nxt_task_t *task, void *obj, void *data)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
nxt_list_each(file, cycle->log_files) {
|
nxt_list_each(file, rt->log_files) {
|
||||||
|
|
||||||
/* This allocation cannot fail. */
|
/* This allocation cannot fail. */
|
||||||
new_file = nxt_array_add(new_files);
|
new_file = nxt_array_add(new_files);
|
||||||
@@ -350,7 +362,7 @@ nxt_master_process_sigusr1_handler(nxt_task_t *task, void *obj, void *data)
|
|||||||
new_file->fd = NXT_FILE_INVALID;
|
new_file->fd = NXT_FILE_INVALID;
|
||||||
new_file->log_level = NXT_LOG_CRIT;
|
new_file->log_level = NXT_LOG_CRIT;
|
||||||
|
|
||||||
ret = nxt_file_open(new_file, NXT_FILE_APPEND, NXT_FILE_CREATE_OR_OPEN,
|
ret = nxt_file_open(task, new_file, O_WRONLY | O_APPEND, O_CREAT,
|
||||||
NXT_FILE_OWNER_ACCESS);
|
NXT_FILE_OWNER_ACCESS);
|
||||||
|
|
||||||
if (ret != NXT_OK) {
|
if (ret != NXT_OK) {
|
||||||
@@ -366,9 +378,9 @@ nxt_master_process_sigusr1_handler(nxt_task_t *task, void *obj, void *data)
|
|||||||
if (ret == NXT_OK) {
|
if (ret == NXT_OK) {
|
||||||
n = 0;
|
n = 0;
|
||||||
|
|
||||||
nxt_list_each(file, cycle->log_files) {
|
nxt_list_each(file, rt->log_files) {
|
||||||
|
|
||||||
nxt_port_change_log_file(task, cycle, n, new_file[n].fd);
|
nxt_port_change_log_file(task, rt, n, new_file[n].fd);
|
||||||
/*
|
/*
|
||||||
* The old log file descriptor must be closed at the moment
|
* The old log file descriptor must be closed at the moment
|
||||||
* when no other threads use it. dup2() allows to use the
|
* when no other threads use it. dup2() allows to use the
|
||||||
@@ -392,7 +404,7 @@ fail:
|
|||||||
|
|
||||||
while (n != 0) {
|
while (n != 0) {
|
||||||
if (new_file->fd != NXT_FILE_INVALID) {
|
if (new_file->fd != NXT_FILE_INVALID) {
|
||||||
nxt_file_close(new_file);
|
nxt_file_close(task, new_file);
|
||||||
}
|
}
|
||||||
|
|
||||||
new_file++;
|
new_file++;
|
||||||
@@ -403,164 +415,6 @@ fail:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
|
||||||
nxt_master_process_sigusr2_handler(nxt_task_t *task, void *obj, void *data)
|
|
||||||
{
|
|
||||||
char **env;
|
|
||||||
nxt_int_t ret;
|
|
||||||
nxt_pid_t pid, ppid;
|
|
||||||
nxt_bool_t ignore;
|
|
||||||
nxt_cycle_t *cycle;
|
|
||||||
|
|
||||||
cycle = nxt_thread_cycle();
|
|
||||||
|
|
||||||
/* Is upgrade or reconfiguring in progress? */
|
|
||||||
ignore = (cycle->new_binary != 0) || cycle->reconfiguring;
|
|
||||||
|
|
||||||
ppid = getppid();
|
|
||||||
|
|
||||||
if (ppid == nxt_ppid && ppid != 1) {
|
|
||||||
/*
|
|
||||||
* Ignore the upgrade signal in a new master process if an old
|
|
||||||
* master process is still running. After the old process's exit
|
|
||||||
* getppid() will return 1 (init process pid) or pid of zsched (zone
|
|
||||||
* scheduler) if the processes run in Solaris zone. There is little
|
|
||||||
* race condition between the parent process exit and getting getppid()
|
|
||||||
* for the very start of the new master process execution, so init or
|
|
||||||
* zsched pid may be stored in nxt_ppid. For this reason pid 1 is
|
|
||||||
* tested explicitly. There is no workaround for this race condition
|
|
||||||
* in Solaris zons. To eliminate this race condition in Solaris
|
|
||||||
* zone the old master process should be quit only when both
|
|
||||||
* "nginext.pid.oldbin" (created by the old master process) and
|
|
||||||
* "nginext.pid" (created by the new master process) files exists.
|
|
||||||
*/
|
|
||||||
ignore = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
nxt_log(task, NXT_LOG_NOTICE,
|
|
||||||
"signal %d (%s) recevied, %s, parent pid: %PI",
|
|
||||||
(int) (uintptr_t) obj, data,
|
|
||||||
ignore ? "ignored" : "online binary file upgrade", ppid);
|
|
||||||
|
|
||||||
if (ignore) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
env = nxt_master_process_upgrade_environment(cycle);
|
|
||||||
if (nxt_slow_path(env == NULL)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
cycle->new_binary = -1;
|
|
||||||
|
|
||||||
ret = nxt_cycle_pid_file_create(cycle->oldbin_file, 0);
|
|
||||||
if (nxt_slow_path(ret != NXT_OK)) {
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
pid = nxt_process_execute(nxt_process_argv[0], nxt_process_argv, env);
|
|
||||||
|
|
||||||
if (pid == -1) {
|
|
||||||
cycle->new_binary = 0;
|
|
||||||
(void) nxt_file_delete(cycle->oldbin_file);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
cycle->new_binary = pid;
|
|
||||||
}
|
|
||||||
|
|
||||||
fail:
|
|
||||||
|
|
||||||
/* Zero slot is NGINX variable slot, all other slots must not be free()d. */
|
|
||||||
nxt_free(env[0]);
|
|
||||||
nxt_free(env);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static char **
|
|
||||||
nxt_master_process_upgrade_environment(nxt_cycle_t *cycle)
|
|
||||||
{
|
|
||||||
size_t len;
|
|
||||||
char **env;
|
|
||||||
u_char *p, *end;
|
|
||||||
nxt_uint_t n;
|
|
||||||
nxt_listen_socket_t *ls;
|
|
||||||
|
|
||||||
env = nxt_master_process_upgrade_environment_create(cycle);
|
|
||||||
if (nxt_slow_path(env == NULL)) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
ls = cycle->listen_sockets->elts;
|
|
||||||
n = cycle->listen_sockets->nelts;
|
|
||||||
|
|
||||||
len = sizeof("NGINX=") + n * (NXT_INT_T_LEN + 1);
|
|
||||||
|
|
||||||
p = nxt_malloc(len);
|
|
||||||
|
|
||||||
if (nxt_slow_path(p == NULL)) {
|
|
||||||
nxt_free(env);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
env[0] = (char *) p;
|
|
||||||
end = p + len;
|
|
||||||
|
|
||||||
p = nxt_cpymem(p, "NGINX=", sizeof("NGINX=") - 1);
|
|
||||||
|
|
||||||
do {
|
|
||||||
p = nxt_sprintf(p, end, "%ud;", ls->socket);
|
|
||||||
|
|
||||||
ls++;
|
|
||||||
n--;
|
|
||||||
} while (n != 0);
|
|
||||||
|
|
||||||
*p = '\0';
|
|
||||||
|
|
||||||
return env;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static char **
|
|
||||||
nxt_master_process_upgrade_environment_create(nxt_cycle_t *cycle)
|
|
||||||
{
|
|
||||||
char **env;
|
|
||||||
nxt_uint_t n;
|
|
||||||
|
|
||||||
/* 2 is for "NGINX" variable and the last NULL slot. */
|
|
||||||
n = 2;
|
|
||||||
|
|
||||||
#if (NXT_SETPROCTITLE_ARGV)
|
|
||||||
n++;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
env = nxt_malloc(n * sizeof(char *));
|
|
||||||
if (nxt_slow_path(env == NULL)) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Zero slot is reserved for "NGINX" variable. */
|
|
||||||
n = 1;
|
|
||||||
|
|
||||||
/* TODO: copy env values */
|
|
||||||
|
|
||||||
#if (NXT_SETPROCTITLE_ARGV)
|
|
||||||
|
|
||||||
/* 300 spare bytes for new process title. */
|
|
||||||
env[n++] = (char *)
|
|
||||||
"SPARE=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
|
|
||||||
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
|
|
||||||
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
|
|
||||||
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
|
|
||||||
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
env[n] = NULL;
|
|
||||||
|
|
||||||
return env;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
nxt_master_process_sigchld_handler(nxt_task_t *task, void *obj, void *data)
|
nxt_master_process_sigchld_handler(nxt_task_t *task, void *obj, void *data)
|
||||||
{
|
{
|
||||||
@@ -619,38 +473,36 @@ nxt_master_process_sigchld_handler(nxt_task_t *task, void *obj, void *data)
|
|||||||
static void
|
static void
|
||||||
nxt_master_cleanup_worker_process(nxt_task_t *task, nxt_pid_t pid)
|
nxt_master_cleanup_worker_process(nxt_task_t *task, nxt_pid_t pid)
|
||||||
{
|
{
|
||||||
nxt_uint_t i, n, generation;
|
nxt_uint_t i, n;
|
||||||
nxt_port_t *port;
|
nxt_runtime_t *rt;
|
||||||
nxt_cycle_t *cycle;
|
nxt_process_t *process;
|
||||||
|
nxt_process_init_t *init;
|
||||||
|
|
||||||
cycle = nxt_thread_cycle();
|
rt = task->thread->runtime;
|
||||||
|
|
||||||
if (cycle->new_binary == pid) {
|
process = rt->processes->elts;
|
||||||
cycle->new_binary = 0;
|
n = rt->processes->nelts;
|
||||||
|
|
||||||
(void) nxt_file_rename(cycle->oldbin_file, cycle->pid_file);
|
/* A process[0] is the master process. */
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
port = cycle->ports->elts;
|
for (i = 1; i < n; i++) {
|
||||||
n = cycle->ports->nelts;
|
|
||||||
|
|
||||||
for (i = 0; i < n; i++) {
|
if (pid == process[i].pid) {
|
||||||
|
init = process[i].init;
|
||||||
|
|
||||||
if (pid == port[i].pid) {
|
/* TODO: free ports fds. */
|
||||||
generation = port[i].generation;
|
|
||||||
|
|
||||||
nxt_array_remove(cycle->ports, &port[i]);
|
nxt_array_remove(rt->processes, &process[i]);
|
||||||
|
|
||||||
if (nxt_exiting) {
|
if (nxt_exiting) {
|
||||||
nxt_debug(task, "processes %d", n);
|
nxt_debug(task, "processes %d", n);
|
||||||
|
|
||||||
if (n == 2) {
|
if (n == 2) {
|
||||||
nxt_cycle_quit(task, cycle);
|
nxt_runtime_quit(task);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (generation == cycle->process_generation) {
|
} else if (init != NULL) {
|
||||||
(void) nxt_master_create_worker_process(task, cycle);
|
(void) nxt_master_create_worker_process(task, rt, init);
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -4,17 +4,21 @@
|
|||||||
* Copyright (C) NGINX, Inc.
|
* Copyright (C) NGINX, Inc.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _NXT_UNIX_MASTER_PROCESS_H_INCLUDED_
|
#ifndef _NXT_MASTER_PROCESS_H_INCLUDED_
|
||||||
#define _NXT_UNIX_MASTER_PROCESS_H_INCLUDED_
|
#define _NXT_MASTER_PROCESS_H_INCLUDED_
|
||||||
|
|
||||||
|
|
||||||
nxt_int_t nxt_master_process_start(nxt_thread_t *thr, nxt_task_t *task,
|
nxt_int_t nxt_master_process_start(nxt_thread_t *thr, nxt_task_t *task,
|
||||||
nxt_cycle_t *cycle);
|
nxt_runtime_t *runtime);
|
||||||
void nxt_master_stop_worker_processes(nxt_task_t *task, nxt_cycle_t *cycle);
|
void nxt_master_stop_worker_processes(nxt_task_t *task, nxt_runtime_t *runtime);
|
||||||
void nxt_worker_process_start(void *data);
|
|
||||||
|
nxt_int_t nxt_controller_start(nxt_task_t *task, nxt_runtime_t *rt);
|
||||||
|
nxt_int_t nxt_router_start(nxt_task_t *task, nxt_runtime_t *rt);
|
||||||
|
|
||||||
|
|
||||||
|
extern nxt_port_handler_t nxt_worker_process_port_handlers[];
|
||||||
extern const nxt_sig_event_t nxt_master_process_signals[];
|
extern const nxt_sig_event_t nxt_master_process_signals[];
|
||||||
|
extern const nxt_sig_event_t nxt_worker_process_signals[];
|
||||||
|
|
||||||
|
|
||||||
#endif /* _NXT_UNIX_MASTER_PROCESS_H_INCLUDED_ */
|
#endif /* _NXT_MASTER_PROCESS_H_INCLUDED_ */
|
||||||
|
|||||||
@@ -126,16 +126,19 @@ nxt_mem_pool_create(size_t size)
|
|||||||
void
|
void
|
||||||
nxt_mem_pool_destroy(nxt_mem_pool_t *mp)
|
nxt_mem_pool_destroy(nxt_mem_pool_t *mp)
|
||||||
{
|
{
|
||||||
|
nxt_task_t *task;
|
||||||
nxt_mem_pool_ext_t *ext;
|
nxt_mem_pool_ext_t *ext;
|
||||||
nxt_mem_pool_chunk_t *chunk, *next;
|
nxt_mem_pool_chunk_t *chunk, *next;
|
||||||
nxt_mem_pool_cleanup_t *mpcl;
|
nxt_mem_pool_cleanup_t *mpcl;
|
||||||
|
|
||||||
|
task = NULL;
|
||||||
|
|
||||||
nxt_mem_pool_thread_assert(mp);
|
nxt_mem_pool_thread_assert(mp);
|
||||||
|
|
||||||
for (mpcl = mp->cleanup; mpcl != NULL; mpcl = mpcl->next) {
|
for (mpcl = mp->cleanup; mpcl != NULL; mpcl = mpcl->next) {
|
||||||
if (mpcl->handler != NULL) {
|
if (mpcl->handler != NULL) {
|
||||||
nxt_thread_log_debug("mem pool cleanup: %p", mpcl);
|
nxt_thread_log_debug("mem pool cleanup: %p", mpcl);
|
||||||
mpcl->handler(mpcl->data);
|
mpcl->handler(task, mpcl->data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
#define NXT_MEM_POOL_MIN_EXT_SIZE nxt_pagesize
|
#define NXT_MEM_POOL_MIN_EXT_SIZE nxt_pagesize
|
||||||
|
|
||||||
|
|
||||||
typedef void (*nxt_mem_pool_cleanup_handler_t)(void *data);
|
typedef void (*nxt_mem_pool_cleanup_handler_t)(nxt_task_t *task, void *data);
|
||||||
typedef struct nxt_mem_pool_cleanup_s nxt_mem_pool_cleanup_t;
|
typedef struct nxt_mem_pool_cleanup_s nxt_mem_pool_cleanup_t;
|
||||||
typedef struct nxt_mem_pool_cache_s nxt_mem_pool_cache_t;
|
typedef struct nxt_mem_pool_cache_s nxt_mem_pool_cache_t;
|
||||||
typedef struct nxt_mem_pool_chunk_s nxt_mem_pool_chunk_t;
|
typedef struct nxt_mem_pool_chunk_s nxt_mem_pool_chunk_t;
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
#include <nxt_main.h>
|
#include <nxt_main.h>
|
||||||
|
|
||||||
|
|
||||||
static void nxt_mem_pool_file_cleanup_handler(void *data);
|
static void nxt_mem_pool_file_cleanup_handler(nxt_task_t *task, void *data);
|
||||||
|
|
||||||
|
|
||||||
nxt_mem_pool_cleanup_t *
|
nxt_mem_pool_cleanup_t *
|
||||||
@@ -27,13 +27,13 @@ nxt_mem_pool_file_cleanup(nxt_mem_pool_t *mp, nxt_file_t *file)
|
|||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
nxt_mem_pool_file_cleanup_handler(void *data)
|
nxt_mem_pool_file_cleanup_handler(nxt_task_t *task, void *data)
|
||||||
{
|
{
|
||||||
nxt_file_t *file;
|
nxt_file_t *file;
|
||||||
|
|
||||||
file = data;
|
file = data;
|
||||||
|
|
||||||
if (file->fd != NXT_FILE_INVALID) {
|
if (file->fd != NXT_FILE_INVALID) {
|
||||||
nxt_file_close(file);
|
nxt_file_close(task, file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -507,62 +507,62 @@ nxt_php_register_variables(zval *track_vars_array TSRMLS_DC)
|
|||||||
nxt_log_debug(r->log, "php register variables");
|
nxt_log_debug(r->log, "php register variables");
|
||||||
|
|
||||||
php_register_variable_safe((char *) "PHP_SELF",
|
php_register_variable_safe((char *) "PHP_SELF",
|
||||||
(char *) r->header.path.data,
|
(char *) r->header.path.data,
|
||||||
ctx->script_name_len, track_vars_array TSRMLS_CC);
|
ctx->script_name_len, track_vars_array TSRMLS_CC);
|
||||||
|
|
||||||
php_register_variable_safe((char *) "SERVER_PROTOCOL",
|
php_register_variable_safe((char *) "SERVER_PROTOCOL",
|
||||||
(char *) r->header.version.data,
|
(char *) r->header.version.data,
|
||||||
r->header.version.len, track_vars_array TSRMLS_CC);
|
r->header.version.len, track_vars_array TSRMLS_CC);
|
||||||
|
|
||||||
#if ABS_MODE
|
#if ABS_MODE
|
||||||
php_register_variable_safe((char *) "SCRIPT_NAME",
|
php_register_variable_safe((char *) "SCRIPT_NAME",
|
||||||
(char *) nxt_php_script.data,
|
(char *) nxt_php_script.data,
|
||||||
nxt_php_script.len, track_vars_array TSRMLS_CC);
|
nxt_php_script.len, track_vars_array TSRMLS_CC);
|
||||||
|
|
||||||
php_register_variable_safe((char *) "SCRIPT_FILENAME",
|
php_register_variable_safe((char *) "SCRIPT_FILENAME",
|
||||||
(char *) nxt_php_path.data,
|
(char *) nxt_php_path.data,
|
||||||
nxt_php_path.len, track_vars_array TSRMLS_CC);
|
nxt_php_path.len, track_vars_array TSRMLS_CC);
|
||||||
|
|
||||||
php_register_variable_safe((char *) "DOCUMENT_ROOT",
|
php_register_variable_safe((char *) "DOCUMENT_ROOT",
|
||||||
(char *) nxt_php_root.data,
|
(char *) nxt_php_root.data,
|
||||||
nxt_php_root.len, track_vars_array TSRMLS_CC);
|
nxt_php_root.len, track_vars_array TSRMLS_CC);
|
||||||
#else
|
#else
|
||||||
php_register_variable_safe((char *) "SCRIPT_NAME",
|
php_register_variable_safe((char *) "SCRIPT_NAME",
|
||||||
(char *) r->header.path.data,
|
(char *) r->header.path.data,
|
||||||
ctx->script_name_len, track_vars_array TSRMLS_CC);
|
ctx->script_name_len, track_vars_array TSRMLS_CC);
|
||||||
|
|
||||||
php_register_variable_safe((char *) "SCRIPT_FILENAME",
|
php_register_variable_safe((char *) "SCRIPT_FILENAME",
|
||||||
(char *) ctx->script.data, ctx->script.len,
|
(char *) ctx->script.data, ctx->script.len,
|
||||||
track_vars_array TSRMLS_CC);
|
track_vars_array TSRMLS_CC);
|
||||||
|
|
||||||
php_register_variable_safe((char *) "DOCUMENT_ROOT", (char *) root,
|
php_register_variable_safe((char *) "DOCUMENT_ROOT", (char *) root,
|
||||||
sizeof(root) - 1, track_vars_array TSRMLS_CC);
|
sizeof(root) - 1, track_vars_array TSRMLS_CC);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
php_register_variable_safe((char *) "REQUEST_METHOD",
|
php_register_variable_safe((char *) "REQUEST_METHOD",
|
||||||
(char *) r->header.method.data,
|
(char *) r->header.method.data,
|
||||||
r->header.method.len, track_vars_array TSRMLS_CC);
|
r->header.method.len, track_vars_array TSRMLS_CC);
|
||||||
|
|
||||||
php_register_variable_safe((char *) "REQUEST_URI",
|
php_register_variable_safe((char *) "REQUEST_URI",
|
||||||
(char *) r->header.path.data,
|
(char *) r->header.path.data,
|
||||||
r->header.path.len, track_vars_array TSRMLS_CC);
|
r->header.path.len, track_vars_array TSRMLS_CC);
|
||||||
|
|
||||||
if (ctx->query.data != NULL) {
|
if (ctx->query.data != NULL) {
|
||||||
php_register_variable_safe((char *) "QUERY_STRING",
|
php_register_variable_safe((char *) "QUERY_STRING",
|
||||||
(char *) ctx->query.data,
|
(char *) ctx->query.data,
|
||||||
ctx->query.len, track_vars_array TSRMLS_CC);
|
ctx->query.len, track_vars_array TSRMLS_CC);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctx->content_type != NULL) {
|
if (ctx->content_type != NULL) {
|
||||||
php_register_variable_safe((char *) "CONTENT_TYPE",
|
php_register_variable_safe((char *) "CONTENT_TYPE",
|
||||||
(char *) ctx->content_type->data,
|
(char *) ctx->content_type->data,
|
||||||
ctx->content_type->len, track_vars_array TSRMLS_CC);
|
ctx->content_type->len, track_vars_array TSRMLS_CC);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctx->content_length != NULL) {
|
if (ctx->content_length != NULL) {
|
||||||
php_register_variable_safe((char *) "CONTENT_LENGTH",
|
php_register_variable_safe((char *) "CONTENT_LENGTH",
|
||||||
(char *) ctx->content_length->data,
|
(char *) ctx->content_length->data,
|
||||||
ctx->content_length->len, track_vars_array TSRMLS_CC);
|
ctx->content_length->len, track_vars_array TSRMLS_CC);
|
||||||
}
|
}
|
||||||
|
|
||||||
var = nxt_mem_nalloc(r->mem_pool, sizeof(prefix) + ctx->max_name + 1);
|
var = nxt_mem_nalloc(r->mem_pool, sizeof(prefix) + ctx->max_name + 1);
|
||||||
|
|||||||
100
src/nxt_port.c
100
src/nxt_port.c
@@ -5,7 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <nxt_main.h>
|
#include <nxt_main.h>
|
||||||
#include <nxt_cycle.h>
|
#include <nxt_runtime.h>
|
||||||
#include <nxt_port.h>
|
#include <nxt_port.h>
|
||||||
|
|
||||||
|
|
||||||
@@ -29,18 +29,26 @@ nxt_port_create(nxt_thread_t *thread, nxt_port_t *port,
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
nxt_port_write(nxt_task_t *task, nxt_cycle_t *cycle, nxt_uint_t type,
|
nxt_port_write(nxt_task_t *task, nxt_runtime_t *rt, nxt_uint_t type,
|
||||||
nxt_fd_t fd, uint32_t stream, nxt_buf_t *b)
|
nxt_fd_t fd, uint32_t stream, nxt_buf_t *b)
|
||||||
{
|
{
|
||||||
nxt_uint_t i, n;
|
nxt_uint_t i, n, nprocesses, nports;
|
||||||
nxt_port_t *port;
|
nxt_port_t *port;
|
||||||
|
nxt_process_t *process;
|
||||||
|
|
||||||
port = cycle->ports->elts;
|
process = rt->processes->elts;
|
||||||
n = cycle->ports->nelts;
|
nprocesses = rt->processes->nelts;
|
||||||
|
|
||||||
for (i = 0; i < n; i++) {
|
for (i = 0; i < nprocesses; i++) {
|
||||||
if (nxt_pid != port[i].pid) {
|
|
||||||
(void) nxt_port_socket_write(task, &port[i], type, fd, stream, b);
|
if (nxt_pid != process[i].pid) {
|
||||||
|
port = process[i].ports->elts;
|
||||||
|
nports = process[i].ports->nelts;
|
||||||
|
|
||||||
|
for (n = 0; n < nports; n++) {
|
||||||
|
(void) nxt_port_socket_write(task, &port[n], type,
|
||||||
|
fd, stream, b);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -70,20 +78,21 @@ nxt_port_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg)
|
|||||||
void
|
void
|
||||||
nxt_port_quit_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg)
|
nxt_port_quit_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg)
|
||||||
{
|
{
|
||||||
nxt_cycle_quit(task, NULL);
|
nxt_runtime_quit(task);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
nxt_port_send_new_port(nxt_task_t *task, nxt_cycle_t *cycle,
|
nxt_port_send_new_port(nxt_task_t *task, nxt_runtime_t *rt,
|
||||||
nxt_port_t *new_port)
|
nxt_port_t *new_port)
|
||||||
{
|
{
|
||||||
nxt_buf_t *b;
|
nxt_buf_t *b;
|
||||||
nxt_uint_t i, n;
|
nxt_uint_t i, n;
|
||||||
nxt_port_t *port;
|
nxt_port_t *port;
|
||||||
|
nxt_process_t *process;
|
||||||
nxt_port_msg_new_port_t *msg;
|
nxt_port_msg_new_port_t *msg;
|
||||||
|
|
||||||
n = cycle->ports->nelts;
|
n = rt->processes->nelts;
|
||||||
if (n == 0) {
|
if (n == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -91,34 +100,33 @@ nxt_port_send_new_port(nxt_task_t *task, nxt_cycle_t *cycle,
|
|||||||
nxt_debug(task, "new port %d for process %PI engine %uD",
|
nxt_debug(task, "new port %d for process %PI engine %uD",
|
||||||
new_port->socket.fd, new_port->pid, new_port->engine);
|
new_port->socket.fd, new_port->pid, new_port->engine);
|
||||||
|
|
||||||
port = cycle->ports->elts;
|
process = rt->processes->elts;
|
||||||
|
|
||||||
for (i = 0; i < n; i++) {
|
for (i = 0; i < n; i++) {
|
||||||
|
|
||||||
if (port[i].pid == new_port->pid
|
if (process[i].pid == new_port->pid || process[i].pid == nxt_pid) {
|
||||||
|| port[i].pid == nxt_pid
|
|
||||||
|| port[i].engine != 0)
|
|
||||||
{
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
b = nxt_buf_mem_alloc(port[i].mem_pool, sizeof(nxt_port_data_t), 0);
|
port = process[i].ports->elts;
|
||||||
|
|
||||||
|
b = nxt_buf_mem_alloc(port->mem_pool, sizeof(nxt_port_data_t), 0);
|
||||||
|
|
||||||
if (nxt_slow_path(b == NULL)) {
|
if (nxt_slow_path(b == NULL)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
b->data = &port[i];
|
b->data = port;
|
||||||
b->completion_handler = nxt_port_new_port_buf_completion;
|
b->completion_handler = nxt_port_new_port_buf_completion;
|
||||||
b->mem.free += sizeof(nxt_port_msg_new_port_t);
|
b->mem.free += sizeof(nxt_port_msg_new_port_t);
|
||||||
msg = (nxt_port_msg_new_port_t *) b->mem.pos;
|
msg = (nxt_port_msg_new_port_t *) b->mem.pos;
|
||||||
|
|
||||||
msg->pid = new_port->pid;
|
msg->pid = new_port->pid;
|
||||||
msg->engine = new_port->engine;
|
msg->engine = new_port->engine;
|
||||||
msg->max_size = port[i].max_size;
|
msg->max_size = port->max_size;
|
||||||
msg->max_share = port[i].max_share;
|
msg->max_share = port->max_share;
|
||||||
|
|
||||||
(void) nxt_port_socket_write(task, &port[i], NXT_PORT_MSG_NEW_PORT,
|
(void) nxt_port_socket_write(task, port, NXT_PORT_MSG_NEW_PORT,
|
||||||
new_port->socket.fd, 0, b);
|
new_port->socket.fd, 0, b);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -143,13 +151,19 @@ void
|
|||||||
nxt_port_new_port_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg)
|
nxt_port_new_port_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg)
|
||||||
{
|
{
|
||||||
nxt_port_t *port;
|
nxt_port_t *port;
|
||||||
nxt_cycle_t *cycle;
|
nxt_process_t *process;
|
||||||
|
nxt_runtime_t *rt;
|
||||||
nxt_mem_pool_t *mp;
|
nxt_mem_pool_t *mp;
|
||||||
nxt_port_msg_new_port_t *new_port_msg;
|
nxt_port_msg_new_port_t *new_port_msg;
|
||||||
|
|
||||||
cycle = nxt_thread_cycle();
|
rt = task->thread->runtime;
|
||||||
|
|
||||||
port = nxt_array_add(cycle->ports);
|
process = nxt_runtime_new_process(rt);
|
||||||
|
if (nxt_slow_path(process == NULL)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
port = nxt_array_zero_add(process->ports);
|
||||||
if (nxt_slow_path(port == NULL)) {
|
if (nxt_slow_path(port == NULL)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -167,6 +181,8 @@ nxt_port_new_port_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg)
|
|||||||
nxt_debug(task, "new port %d received for process %PI engine %uD",
|
nxt_debug(task, "new port %d received for process %PI engine %uD",
|
||||||
msg->fd, new_port_msg->pid, new_port_msg->engine);
|
msg->fd, new_port_msg->pid, new_port_msg->engine);
|
||||||
|
|
||||||
|
process->pid = new_port_msg->pid;
|
||||||
|
|
||||||
port->pid = new_port_msg->pid;
|
port->pid = new_port_msg->pid;
|
||||||
port->engine = new_port_msg->engine;
|
port->engine = new_port_msg->engine;
|
||||||
port->pair[0] = -1;
|
port->pair[0] = -1;
|
||||||
@@ -183,27 +199,29 @@ nxt_port_new_port_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg)
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
nxt_port_change_log_file(nxt_task_t *task, nxt_cycle_t *cycle,
|
nxt_port_change_log_file(nxt_task_t *task, nxt_runtime_t *rt, nxt_uint_t slot,
|
||||||
nxt_uint_t slot, nxt_fd_t fd)
|
nxt_fd_t fd)
|
||||||
{
|
{
|
||||||
nxt_buf_t *b;
|
nxt_buf_t *b;
|
||||||
nxt_uint_t i, n;
|
nxt_uint_t i, n;
|
||||||
nxt_port_t *port;
|
nxt_port_t *port;
|
||||||
|
nxt_process_t *process;
|
||||||
|
|
||||||
n = cycle->ports->nelts;
|
n = rt->processes->nelts;
|
||||||
if (n == 0) {
|
if (n == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
nxt_debug(task, "change log file #%ui fd:%FD", slot, fd);
|
nxt_debug(task, "change log file #%ui fd:%FD", slot, fd);
|
||||||
|
|
||||||
port = cycle->ports->elts;
|
process = rt->processes->elts;
|
||||||
|
|
||||||
/* port[0] is master process port. */
|
/* process[0] is master process. */
|
||||||
|
|
||||||
for (i = 1; i < n; i++) {
|
for (i = 1; i < n; i++) {
|
||||||
b = nxt_buf_mem_alloc(port[i].mem_pool, sizeof(nxt_port_data_t), 0);
|
port = process[i].ports->elts;
|
||||||
|
|
||||||
|
b = nxt_buf_mem_alloc(port->mem_pool, sizeof(nxt_port_data_t), 0);
|
||||||
if (nxt_slow_path(b == NULL)) {
|
if (nxt_slow_path(b == NULL)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -211,7 +229,7 @@ nxt_port_change_log_file(nxt_task_t *task, nxt_cycle_t *cycle,
|
|||||||
*(nxt_uint_t *) b->mem.pos = slot;
|
*(nxt_uint_t *) b->mem.pos = slot;
|
||||||
b->mem.free += sizeof(nxt_uint_t);
|
b->mem.free += sizeof(nxt_uint_t);
|
||||||
|
|
||||||
(void) nxt_port_socket_write(task, &port[i], NXT_PORT_MSG_CHANGE_FILE,
|
(void) nxt_port_socket_write(task, port, NXT_PORT_MSG_CHANGE_FILE,
|
||||||
fd, 0, b);
|
fd, 0, b);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -220,17 +238,17 @@ nxt_port_change_log_file(nxt_task_t *task, nxt_cycle_t *cycle,
|
|||||||
void
|
void
|
||||||
nxt_port_change_log_file_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg)
|
nxt_port_change_log_file_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg)
|
||||||
{
|
{
|
||||||
nxt_buf_t *b;
|
nxt_buf_t *b;
|
||||||
nxt_uint_t slot;
|
nxt_uint_t slot;
|
||||||
nxt_file_t *log_file;
|
nxt_file_t *log_file;
|
||||||
nxt_cycle_t *cycle;
|
nxt_runtime_t *rt;
|
||||||
|
|
||||||
cycle = nxt_thread_cycle();
|
rt = task->thread->runtime;
|
||||||
|
|
||||||
b = msg->buf;
|
b = msg->buf;
|
||||||
slot = *(nxt_uint_t *) b->mem.pos;
|
slot = *(nxt_uint_t *) b->mem.pos;
|
||||||
|
|
||||||
log_file = nxt_list_elt(cycle->log_files, slot);
|
log_file = nxt_list_elt(rt->log_files, slot);
|
||||||
|
|
||||||
nxt_debug(task, "change log file %FD:%FD", msg->fd, log_file->fd);
|
nxt_debug(task, "change log file %FD:%FD", msg->fd, log_file->fd);
|
||||||
|
|
||||||
|
|||||||
@@ -8,9 +8,6 @@
|
|||||||
#define _NXT_PORT_H_INCLUDED_
|
#define _NXT_PORT_H_INCLUDED_
|
||||||
|
|
||||||
|
|
||||||
typedef struct nxt_port_s nxt_port_t;
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t stream;
|
uint32_t stream;
|
||||||
|
|
||||||
@@ -28,17 +25,14 @@ typedef struct {
|
|||||||
} nxt_port_send_msg_t;
|
} nxt_port_send_msg_t;
|
||||||
|
|
||||||
|
|
||||||
typedef struct nxt_port_recv_msg_s {
|
struct nxt_port_recv_msg_s {
|
||||||
uint32_t stream;
|
uint32_t stream;
|
||||||
uint16_t type;
|
uint16_t type;
|
||||||
|
|
||||||
nxt_fd_t fd;
|
nxt_fd_t fd;
|
||||||
nxt_buf_t *buf;
|
nxt_buf_t *buf;
|
||||||
nxt_port_t *port;
|
nxt_port_t *port;
|
||||||
} nxt_port_recv_msg_t;
|
};
|
||||||
|
|
||||||
|
|
||||||
typedef void (*nxt_port_handler_t)(nxt_task_t *task, nxt_port_recv_msg_t *msg);
|
|
||||||
|
|
||||||
|
|
||||||
struct nxt_port_s {
|
struct nxt_port_s {
|
||||||
@@ -61,7 +55,6 @@ struct nxt_port_s {
|
|||||||
|
|
||||||
nxt_pid_t pid;
|
nxt_pid_t pid;
|
||||||
uint32_t engine;
|
uint32_t engine;
|
||||||
uint32_t generation;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -105,11 +98,11 @@ nxt_int_t nxt_port_socket_write(nxt_task_t *task, nxt_port_t *port,
|
|||||||
|
|
||||||
void nxt_port_create(nxt_thread_t *thread, nxt_port_t *port,
|
void nxt_port_create(nxt_thread_t *thread, nxt_port_t *port,
|
||||||
nxt_port_handler_t *handlers);
|
nxt_port_handler_t *handlers);
|
||||||
void nxt_port_write(nxt_task_t *task, nxt_cycle_t *cycle, nxt_uint_t type,
|
void nxt_port_write(nxt_task_t *task, nxt_runtime_t *rt, nxt_uint_t type,
|
||||||
nxt_fd_t fd, uint32_t stream, nxt_buf_t *b);
|
nxt_fd_t fd, uint32_t stream, nxt_buf_t *b);
|
||||||
void nxt_port_send_new_port(nxt_task_t *task, nxt_cycle_t *cycle,
|
void nxt_port_send_new_port(nxt_task_t *task, nxt_runtime_t *rt,
|
||||||
nxt_port_t *port);
|
nxt_port_t *port);
|
||||||
void nxt_port_change_log_file(nxt_task_t *task, nxt_cycle_t *cycle,
|
void nxt_port_change_log_file(nxt_task_t *task, nxt_runtime_t *rt,
|
||||||
nxt_uint_t slot, nxt_fd_t fd);
|
nxt_uint_t slot, nxt_fd_t fd);
|
||||||
|
|
||||||
void nxt_port_quit_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg);
|
void nxt_port_quit_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg);
|
||||||
|
|||||||
@@ -5,9 +5,11 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <nxt_main.h>
|
#include <nxt_main.h>
|
||||||
|
#include <nxt_master_process.h>
|
||||||
|
|
||||||
|
|
||||||
static nxt_int_t nxt_user_groups_get(nxt_user_cred_t *uc);
|
static void nxt_process_start(nxt_task_t *task, nxt_process_init_t *process);
|
||||||
|
static nxt_int_t nxt_user_groups_get(nxt_task_t *task, nxt_user_cred_t *uc);
|
||||||
|
|
||||||
|
|
||||||
/* A cached process pid. */
|
/* A cached process pid. */
|
||||||
@@ -18,20 +20,17 @@ nxt_pid_t nxt_ppid;
|
|||||||
|
|
||||||
|
|
||||||
nxt_pid_t
|
nxt_pid_t
|
||||||
nxt_process_create(nxt_process_start_t start, void *data, const char *name)
|
nxt_process_create(nxt_task_t *task, nxt_process_init_t *process)
|
||||||
{
|
{
|
||||||
nxt_pid_t pid;
|
nxt_pid_t pid;
|
||||||
nxt_thread_t *thr;
|
|
||||||
|
|
||||||
thr = nxt_thread();
|
|
||||||
|
|
||||||
pid = fork();
|
pid = fork();
|
||||||
|
|
||||||
switch (pid) {
|
switch (pid) {
|
||||||
|
|
||||||
case -1:
|
case -1:
|
||||||
nxt_log_alert(thr->log, "fork() failed while creating \"%s\" %E",
|
nxt_log(task, NXT_LOG_CRIT, "fork() failed while creating \"%s\" %E",
|
||||||
name, nxt_errno);
|
process->name, nxt_errno);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0:
|
case 0:
|
||||||
@@ -39,14 +38,14 @@ nxt_process_create(nxt_process_start_t start, void *data, const char *name)
|
|||||||
nxt_pid = getpid();
|
nxt_pid = getpid();
|
||||||
|
|
||||||
/* Clean inherited cached thread tid. */
|
/* Clean inherited cached thread tid. */
|
||||||
thr->tid = 0;
|
task->thread->tid = 0;
|
||||||
|
|
||||||
start(data);
|
nxt_process_start(task, process);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
/* A parent. */
|
/* A parent. */
|
||||||
nxt_log_debug(thr->log, "fork(): %PI", pid);
|
nxt_debug(task, "fork(\"%s\"): %PI", process->name, pid);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,6 +53,73 @@ nxt_process_create(nxt_process_start_t start, void *data, const char *name)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
nxt_process_start(nxt_task_t *task, nxt_process_init_t *process)
|
||||||
|
{
|
||||||
|
nxt_int_t ret;
|
||||||
|
nxt_thread_t *thread;
|
||||||
|
nxt_runtime_t *rt;
|
||||||
|
nxt_event_engine_t *engine;
|
||||||
|
const nxt_event_interface_t *interface;
|
||||||
|
|
||||||
|
nxt_log(task, NXT_LOG_INFO, "%s started", process->name);
|
||||||
|
|
||||||
|
nxt_process_title(task, "nginext: %s", process->name);
|
||||||
|
|
||||||
|
nxt_random_init(&nxt_random_data);
|
||||||
|
|
||||||
|
if (process->user_cred != NULL && getuid() == 0) {
|
||||||
|
/* Super-user. */
|
||||||
|
|
||||||
|
ret = nxt_user_cred_set(task, process->user_cred);
|
||||||
|
if (ret != NXT_OK) {
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
thread = task->thread;
|
||||||
|
rt = thread->runtime;
|
||||||
|
|
||||||
|
rt->type = process->type;
|
||||||
|
|
||||||
|
engine = thread->engine;
|
||||||
|
|
||||||
|
/* Update inherited master process event engine and signals processing. */
|
||||||
|
engine->signals->sigev = process->signals;
|
||||||
|
|
||||||
|
interface = nxt_service_get(rt->services, "engine", rt->engine);
|
||||||
|
if (interface == NULL) {
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nxt_event_engine_change(engine, interface, rt->batch) != NXT_OK) {
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
nxt_port_read_close(process->master_port);
|
||||||
|
nxt_port_write_enable(task, process->master_port);
|
||||||
|
|
||||||
|
/* A worker process port. */
|
||||||
|
nxt_port_create(thread, process->port, process->port_handlers);
|
||||||
|
|
||||||
|
ret = nxt_runtime_thread_pool_create(thread, rt, rt->auxiliary_threads,
|
||||||
|
60000 * 1000000LL);
|
||||||
|
if (ret != NXT_OK) {
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = process->start(task, rt);
|
||||||
|
|
||||||
|
if (ret == NXT_OK) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fail:
|
||||||
|
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#if (NXT_HAVE_POSIX_SPAWN)
|
#if (NXT_HAVE_POSIX_SPAWN)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -76,14 +142,15 @@ nxt_process_create(nxt_process_start_t start, void *data, const char *name)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
nxt_pid_t
|
nxt_pid_t
|
||||||
nxt_process_execute(char *name, char **argv, char **envp)
|
nxt_process_execute(nxt_task_t *task, char *name, char **argv, char **envp)
|
||||||
{
|
{
|
||||||
nxt_pid_t pid;
|
nxt_pid_t pid;
|
||||||
|
|
||||||
nxt_thread_log_debug("posix_spawn(\"%s\")", name);
|
nxt_debug(task, "posix_spawn(\"%s\")", name);
|
||||||
|
|
||||||
if (posix_spawn(&pid, name, NULL, NULL, argv, envp) != 0) {
|
if (posix_spawn(&pid, name, NULL, NULL, argv, envp) != 0) {
|
||||||
nxt_thread_log_alert("posix_spawn(\"%s\") failed %E", name, nxt_errno);
|
nxt_log(task, NXT_LOG_CRIT, "posix_spawn(\"%s\") failed %E",
|
||||||
|
name, nxt_errno);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,7 +160,7 @@ nxt_process_execute(char *name, char **argv, char **envp)
|
|||||||
#else
|
#else
|
||||||
|
|
||||||
nxt_pid_t
|
nxt_pid_t
|
||||||
nxt_process_execute(char *name, char **argv, char **envp)
|
nxt_process_execute(nxt_task_t *task, char *name, char **argv, char **envp)
|
||||||
{
|
{
|
||||||
nxt_pid_t pid;
|
nxt_pid_t pid;
|
||||||
|
|
||||||
@@ -109,24 +176,26 @@ nxt_process_execute(char *name, char **argv, char **envp)
|
|||||||
switch (pid) {
|
switch (pid) {
|
||||||
|
|
||||||
case -1:
|
case -1:
|
||||||
nxt_thread_log_alert("vfork() failed while executing \"%s\" %E",
|
nxt_log(task, NXT_LOG_CRIT, "vfork() failed while executing \"%s\" %E",
|
||||||
name, nxt_errno);
|
name, nxt_errno);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0:
|
case 0:
|
||||||
/* A child. */
|
/* A child. */
|
||||||
nxt_thread_log_debug("execve(\"%s\")", name);
|
nxt_debug(task, "execve(\"%s\")", name);
|
||||||
|
|
||||||
(void) execve(name, argv, envp);
|
(void) execve(name, argv, envp);
|
||||||
|
|
||||||
nxt_thread_log_alert("execve(\"%s\") failed %E", name, nxt_errno);
|
nxt_log(task, NXT_LOG_CRIT, "execve(\"%s\") failed %E",
|
||||||
|
name, nxt_errno);
|
||||||
|
|
||||||
exit(1);
|
exit(1);
|
||||||
|
nxt_unreachable();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
/* A parent. */
|
/* A parent. */
|
||||||
nxt_thread_log_debug("vfork(): %PI", pid);
|
nxt_debug(task, "vfork(): %PI", pid);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -137,14 +206,11 @@ nxt_process_execute(char *name, char **argv, char **envp)
|
|||||||
|
|
||||||
|
|
||||||
nxt_int_t
|
nxt_int_t
|
||||||
nxt_process_daemon(void)
|
nxt_process_daemon(nxt_task_t *task)
|
||||||
{
|
{
|
||||||
nxt_fd_t fd;
|
nxt_fd_t fd;
|
||||||
nxt_pid_t pid;
|
nxt_pid_t pid;
|
||||||
const char *msg;
|
const char *msg;
|
||||||
nxt_thread_t *thr;
|
|
||||||
|
|
||||||
thr = nxt_thread();
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* fork() followed by a parent process's exit() detaches a child process
|
* fork() followed by a parent process's exit() detaches a child process
|
||||||
@@ -166,7 +232,7 @@ nxt_process_daemon(void)
|
|||||||
|
|
||||||
default:
|
default:
|
||||||
/* A parent. */
|
/* A parent. */
|
||||||
nxt_log_debug(thr->log, "fork(): %PI", pid);
|
nxt_debug(task, "fork(): %PI", pid);
|
||||||
exit(0);
|
exit(0);
|
||||||
nxt_unreachable();
|
nxt_unreachable();
|
||||||
}
|
}
|
||||||
@@ -174,14 +240,14 @@ nxt_process_daemon(void)
|
|||||||
nxt_pid = getpid();
|
nxt_pid = getpid();
|
||||||
|
|
||||||
/* Clean inherited cached thread tid. */
|
/* Clean inherited cached thread tid. */
|
||||||
thr->tid = 0;
|
task->thread->tid = 0;
|
||||||
|
|
||||||
nxt_log_debug(thr->log, "daemon");
|
nxt_debug(task, "daemon");
|
||||||
|
|
||||||
/* Detach from controlling terminal. */
|
/* Detach from controlling terminal. */
|
||||||
|
|
||||||
if (setsid() == -1) {
|
if (setsid() == -1) {
|
||||||
nxt_log_emerg(thr->log, "setsid() failed %E", nxt_errno);
|
nxt_log(task, NXT_LOG_CRIT, "setsid() failed %E", nxt_errno);
|
||||||
return NXT_ERROR;
|
return NXT_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -217,7 +283,7 @@ nxt_process_daemon(void)
|
|||||||
|
|
||||||
fail:
|
fail:
|
||||||
|
|
||||||
nxt_log_emerg(thr->log, msg, nxt_errno);
|
nxt_log(task, NXT_LOG_CRIT, msg, nxt_errno);
|
||||||
|
|
||||||
return NXT_ERROR;
|
return NXT_ERROR;
|
||||||
}
|
}
|
||||||
@@ -236,7 +302,7 @@ nxt_nanosleep(nxt_nsec_t ns)
|
|||||||
|
|
||||||
|
|
||||||
nxt_int_t
|
nxt_int_t
|
||||||
nxt_user_cred_get(nxt_user_cred_t *uc, const char *group)
|
nxt_user_cred_get(nxt_task_t *task, nxt_user_cred_t *uc, const char *group)
|
||||||
{
|
{
|
||||||
struct group *grp;
|
struct group *grp;
|
||||||
struct passwd *pwd;
|
struct passwd *pwd;
|
||||||
@@ -244,7 +310,8 @@ nxt_user_cred_get(nxt_user_cred_t *uc, const char *group)
|
|||||||
pwd = getpwnam(uc->user);
|
pwd = getpwnam(uc->user);
|
||||||
|
|
||||||
if (nxt_slow_path(pwd == NULL)) {
|
if (nxt_slow_path(pwd == NULL)) {
|
||||||
nxt_thread_log_emerg("getpwnam(%s) failed %E", uc->user, nxt_errno);
|
nxt_log(task, NXT_LOG_CRIT, "getpwnam(%s) failed %E",
|
||||||
|
uc->user, nxt_errno);
|
||||||
return NXT_ERROR;
|
return NXT_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -255,7 +322,8 @@ nxt_user_cred_get(nxt_user_cred_t *uc, const char *group)
|
|||||||
grp = getgrnam(group);
|
grp = getgrnam(group);
|
||||||
|
|
||||||
if (nxt_slow_path(grp == NULL)) {
|
if (nxt_slow_path(grp == NULL)) {
|
||||||
nxt_thread_log_emerg("getgrnam(%s) failed %E", group, nxt_errno);
|
nxt_log(task, NXT_LOG_CRIT, "getgrnam(%s) failed %E",
|
||||||
|
group, nxt_errno);
|
||||||
return NXT_ERROR;
|
return NXT_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -263,7 +331,7 @@ nxt_user_cred_get(nxt_user_cred_t *uc, const char *group)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (getuid() == 0) {
|
if (getuid() == 0) {
|
||||||
return nxt_user_groups_get(uc);
|
return nxt_user_groups_get(task, uc);
|
||||||
}
|
}
|
||||||
|
|
||||||
return NXT_OK;
|
return NXT_OK;
|
||||||
@@ -297,7 +365,7 @@ nxt_user_cred_get(nxt_user_cred_t *uc, const char *group)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
static nxt_int_t
|
static nxt_int_t
|
||||||
nxt_user_groups_get(nxt_user_cred_t *uc)
|
nxt_user_groups_get(nxt_task_t *task, nxt_user_cred_t *uc)
|
||||||
{
|
{
|
||||||
int nsaved, ngroups;
|
int nsaved, ngroups;
|
||||||
nxt_int_t ret;
|
nxt_int_t ret;
|
||||||
@@ -306,11 +374,11 @@ nxt_user_groups_get(nxt_user_cred_t *uc)
|
|||||||
nsaved = getgroups(0, NULL);
|
nsaved = getgroups(0, NULL);
|
||||||
|
|
||||||
if (nsaved == -1) {
|
if (nsaved == -1) {
|
||||||
nxt_thread_log_emerg("getgroups(0, NULL) failed %E", nxt_errno);
|
nxt_log(task, NXT_LOG_CRIT, "getgroups(0, NULL) failed %E", nxt_errno);
|
||||||
return NXT_ERROR;
|
return NXT_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
nxt_thread_log_debug("getgroups(0, NULL): %d", nsaved);
|
nxt_debug(task, "getgroups(0, NULL): %d", nsaved);
|
||||||
|
|
||||||
if (nsaved > NGROUPS_MAX) {
|
if (nsaved > NGROUPS_MAX) {
|
||||||
/* MacOSX case. */
|
/* MacOSX case. */
|
||||||
@@ -328,14 +396,15 @@ nxt_user_groups_get(nxt_user_cred_t *uc)
|
|||||||
nsaved = getgroups(nsaved, saved);
|
nsaved = getgroups(nsaved, saved);
|
||||||
|
|
||||||
if (nsaved == -1) {
|
if (nsaved == -1) {
|
||||||
nxt_thread_log_emerg("getgroups(%d) failed %E", nsaved, nxt_errno);
|
nxt_log(task, NXT_LOG_CRIT, "getgroups(%d) failed %E",
|
||||||
|
nsaved, nxt_errno);
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
nxt_thread_log_debug("getgroups(): %d", nsaved);
|
nxt_debug(task, "getgroups(): %d", nsaved);
|
||||||
|
|
||||||
if (initgroups(uc->user, uc->base_gid) != 0) {
|
if (initgroups(uc->user, uc->base_gid) != 0) {
|
||||||
nxt_thread_log_emerg("initgroups(%s, %d) failed",
|
nxt_log(task, NXT_LOG_CRIT, "initgroups(%s, %d) failed",
|
||||||
uc->user, uc->base_gid);
|
uc->user, uc->base_gid);
|
||||||
goto restore;
|
goto restore;
|
||||||
}
|
}
|
||||||
@@ -343,11 +412,11 @@ nxt_user_groups_get(nxt_user_cred_t *uc)
|
|||||||
ngroups = getgroups(0, NULL);
|
ngroups = getgroups(0, NULL);
|
||||||
|
|
||||||
if (ngroups == -1) {
|
if (ngroups == -1) {
|
||||||
nxt_thread_log_emerg("getgroups(0, NULL) failed %E", nxt_errno);
|
nxt_log(task, NXT_LOG_CRIT, "getgroups(0, NULL) failed %E", nxt_errno);
|
||||||
goto restore;
|
goto restore;
|
||||||
}
|
}
|
||||||
|
|
||||||
nxt_thread_log_debug("getgroups(0, NULL): %d", ngroups);
|
nxt_debug(task, "getgroups(0, NULL): %d", ngroups);
|
||||||
|
|
||||||
uc->gids = nxt_malloc(ngroups * sizeof(nxt_gid_t));
|
uc->gids = nxt_malloc(ngroups * sizeof(nxt_gid_t));
|
||||||
|
|
||||||
@@ -358,7 +427,8 @@ nxt_user_groups_get(nxt_user_cred_t *uc)
|
|||||||
ngroups = getgroups(ngroups, uc->gids);
|
ngroups = getgroups(ngroups, uc->gids);
|
||||||
|
|
||||||
if (ngroups == -1) {
|
if (ngroups == -1) {
|
||||||
nxt_thread_log_emerg("getgroups(%d) failed %E", ngroups, nxt_errno);
|
nxt_log(task, NXT_LOG_CRIT, "getgroups(%d) failed %E",
|
||||||
|
ngroups, nxt_errno);
|
||||||
goto restore;
|
goto restore;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -377,9 +447,9 @@ nxt_user_groups_get(nxt_user_cred_t *uc)
|
|||||||
p = nxt_sprintf(p, end, "%uL:", (uint64_t) uc->gids[i]);
|
p = nxt_sprintf(p, end, "%uL:", (uint64_t) uc->gids[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
nxt_thread_log_debug("user \"%s\" cred: uid:%uL base gid:%uL, gids:%*s",
|
nxt_debug(task, "user \"%s\" cred: uid:%uL base gid:%uL, gids:%*s",
|
||||||
uc->user, (uint64_t) uc->uid,
|
uc->user, (uint64_t) uc->uid, (uint64_t) uc->base_gid,
|
||||||
(uint64_t) uc->base_gid, p - msg, msg);
|
p - msg, msg);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -388,7 +458,8 @@ nxt_user_groups_get(nxt_user_cred_t *uc)
|
|||||||
restore:
|
restore:
|
||||||
|
|
||||||
if (setgroups(nsaved, saved) != 0) {
|
if (setgroups(nsaved, saved) != 0) {
|
||||||
nxt_thread_log_emerg("setgroups(%d) failed %E", nsaved, nxt_errno);
|
nxt_log(task, NXT_LOG_CRIT, "setgroups(%d) failed %E",
|
||||||
|
nsaved, nxt_errno);
|
||||||
ret = NXT_ERROR;
|
ret = NXT_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -401,34 +472,35 @@ fail:
|
|||||||
|
|
||||||
|
|
||||||
nxt_int_t
|
nxt_int_t
|
||||||
nxt_user_cred_set(nxt_user_cred_t *uc)
|
nxt_user_cred_set(nxt_task_t *task, nxt_user_cred_t *uc)
|
||||||
{
|
{
|
||||||
nxt_thread_log_debug("user cred set: \"%s\" uid:%uL base gid:%uL",
|
nxt_debug(task, "user cred set: \"%s\" uid:%uL base gid:%uL",
|
||||||
uc->user, (uint64_t) uc->uid, uc->base_gid);
|
uc->user, (uint64_t) uc->uid, uc->base_gid);
|
||||||
|
|
||||||
if (setgid(uc->base_gid) != 0) {
|
if (setgid(uc->base_gid) != 0) {
|
||||||
nxt_thread_log_emerg("setgid(%d) failed %E", uc->base_gid, nxt_errno);
|
nxt_log(task, NXT_LOG_CRIT, "setgid(%d) failed %E",
|
||||||
|
uc->base_gid, nxt_errno);
|
||||||
return NXT_ERROR;
|
return NXT_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (uc->gids != NULL) {
|
if (uc->gids != NULL) {
|
||||||
if (setgroups(uc->ngroups, uc->gids) != 0) {
|
if (setgroups(uc->ngroups, uc->gids) != 0) {
|
||||||
nxt_thread_log_emerg("setgroups(%i) failed %E",
|
nxt_log(task, NXT_LOG_CRIT, "setgroups(%i) failed %E",
|
||||||
uc->ngroups, nxt_errno);
|
uc->ngroups, nxt_errno);
|
||||||
return NXT_ERROR;
|
return NXT_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
/* MacOSX fallback. */
|
/* MacOSX fallback. */
|
||||||
if (initgroups(uc->user, uc->base_gid) != 0) {
|
if (initgroups(uc->user, uc->base_gid) != 0) {
|
||||||
nxt_thread_log_emerg("initgroups(%s, %d) failed",
|
nxt_log(task, NXT_LOG_CRIT, "initgroups(%s, %d) failed",
|
||||||
uc->user, uc->base_gid);
|
uc->user, uc->base_gid);
|
||||||
return NXT_ERROR;
|
return NXT_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (setuid(uc->uid) != 0) {
|
if (setuid(uc->uid) != 0) {
|
||||||
nxt_thread_log_emerg("setuid(%d) failed %E", uc->uid, nxt_errno);
|
nxt_log(task, NXT_LOG_CRIT, "setuid(%d) failed %E", uc->uid, nxt_errno);
|
||||||
return NXT_ERROR;
|
return NXT_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,62 +4,95 @@
|
|||||||
* Copyright (C) NGINX, Inc.
|
* Copyright (C) NGINX, Inc.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _NXT_UNIX_PROCESS_H_INCLUDED_
|
#ifndef _NXT_PROCESS_H_INCLUDED_
|
||||||
#define _NXT_UNIX_PROCESS_H_INCLUDED_
|
#define _NXT_PROCESS_H_INCLUDED_
|
||||||
|
|
||||||
|
|
||||||
typedef pid_t nxt_pid_t;
|
typedef enum {
|
||||||
|
NXT_PROCESS_SINGLE = 0,
|
||||||
|
NXT_PROCESS_MASTER,
|
||||||
|
NXT_PROCESS_CONTROLLER,
|
||||||
|
NXT_PROCESS_ROUTER,
|
||||||
|
NXT_PROCESS_WORKER,
|
||||||
|
} nxt_process_type_t;
|
||||||
|
|
||||||
|
|
||||||
#define \
|
typedef pid_t nxt_pid_t;
|
||||||
nxt_sched_yield() \
|
typedef uid_t nxt_uid_t;
|
||||||
|
typedef gid_t nxt_gid_t;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
const char *user;
|
||||||
|
nxt_uid_t uid;
|
||||||
|
nxt_gid_t base_gid;
|
||||||
|
nxt_uint_t ngroups;
|
||||||
|
nxt_gid_t *gids;
|
||||||
|
} nxt_user_cred_t;
|
||||||
|
|
||||||
|
typedef struct nxt_process_init_s nxt_process_init_t;
|
||||||
|
typedef nxt_int_t (*nxt_process_star_t)(nxt_task_t *task, nxt_runtime_t *rt);
|
||||||
|
|
||||||
|
|
||||||
|
struct nxt_process_init_s {
|
||||||
|
nxt_process_star_t start;
|
||||||
|
const char *name;
|
||||||
|
nxt_user_cred_t *user_cred;
|
||||||
|
|
||||||
|
nxt_port_t *port;
|
||||||
|
nxt_port_t *master_port;
|
||||||
|
nxt_port_handler_t *port_handlers;
|
||||||
|
const nxt_sig_event_t *signals;
|
||||||
|
|
||||||
|
nxt_process_type_t type:8; /* 3 bits */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
nxt_pid_t pid;
|
||||||
|
nxt_array_t *ports; /* of nxt_port_t */
|
||||||
|
nxt_process_init_t *init;
|
||||||
|
} nxt_process_t;
|
||||||
|
|
||||||
|
|
||||||
|
NXT_EXPORT nxt_pid_t nxt_process_create(nxt_task_t *task,
|
||||||
|
nxt_process_init_t *process);
|
||||||
|
NXT_EXPORT nxt_pid_t nxt_process_execute(nxt_task_t *task, char *name,
|
||||||
|
char **argv, char **envp);
|
||||||
|
NXT_EXPORT nxt_int_t nxt_process_daemon(nxt_task_t *task);
|
||||||
|
NXT_EXPORT void nxt_nanosleep(nxt_nsec_t ns);
|
||||||
|
|
||||||
|
NXT_EXPORT void nxt_process_arguments(nxt_task_t *task, char **orig_argv,
|
||||||
|
char ***orig_envp);
|
||||||
|
|
||||||
|
|
||||||
|
#if (NXT_HAVE_SETPROCTITLE)
|
||||||
|
|
||||||
|
#define nxt_process_title(task, fmt, ...) \
|
||||||
|
setproctitle(fmt, __VA_ARGS__)
|
||||||
|
|
||||||
|
#elif (NXT_LINUX || NXT_SOLARIS || NXT_MACOSX)
|
||||||
|
|
||||||
|
#define NXT_SETPROCTITLE_ARGV 1
|
||||||
|
NXT_EXPORT void nxt_process_title(nxt_task_t *task, const char *fmt, ...);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#define nxt_sched_yield() \
|
||||||
sched_yield()
|
sched_yield()
|
||||||
|
|
||||||
|
|
||||||
#define \
|
|
||||||
nxt_process_id() \
|
|
||||||
nxt_pid
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Solaris declares abort() as __NORETURN,
|
* Solaris declares abort() as __NORETURN,
|
||||||
* raise(SIGABRT) is mostly the same.
|
* raise(SIGABRT) is mostly the same.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define \
|
#define nxt_abort() \
|
||||||
nxt_abort() \
|
|
||||||
(void) raise(SIGABRT)
|
(void) raise(SIGABRT)
|
||||||
|
|
||||||
|
NXT_EXPORT nxt_int_t nxt_user_cred_get(nxt_task_t *task, nxt_user_cred_t *uc,
|
||||||
typedef void (*nxt_process_start_t)(void *data);
|
const char *group);
|
||||||
|
NXT_EXPORT nxt_int_t nxt_user_cred_set(nxt_task_t *task, nxt_user_cred_t *uc);
|
||||||
NXT_EXPORT nxt_pid_t nxt_process_create(nxt_process_start_t start, void *data,
|
|
||||||
const char *name);
|
|
||||||
NXT_EXPORT nxt_pid_t nxt_process_execute(char *name, char **argv, char **envp);
|
|
||||||
NXT_EXPORT nxt_int_t nxt_process_daemon(void);
|
|
||||||
NXT_EXPORT void nxt_nanosleep(nxt_nsec_t ns);
|
|
||||||
|
|
||||||
NXT_EXPORT void nxt_process_arguments(char **orig_argv, char ***orig_envp);
|
|
||||||
|
|
||||||
|
|
||||||
#if (NXT_HAVE_SETPROCTITLE)
|
|
||||||
|
|
||||||
#define \
|
|
||||||
nxt_process_title(title) \
|
|
||||||
setproctitle("%s", title)
|
|
||||||
|
|
||||||
#elif (NXT_LINUX || NXT_SOLARIS || NXT_MACOSX)
|
|
||||||
|
|
||||||
#define NXT_SETPROCTITLE_ARGV 1
|
|
||||||
NXT_EXPORT void nxt_process_title(const char *title);
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
#define \
|
|
||||||
nxt_process_title(title)
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
NXT_EXPORT extern nxt_pid_t nxt_pid;
|
NXT_EXPORT extern nxt_pid_t nxt_pid;
|
||||||
NXT_EXPORT extern nxt_pid_t nxt_ppid;
|
NXT_EXPORT extern nxt_pid_t nxt_ppid;
|
||||||
@@ -67,21 +100,4 @@ NXT_EXPORT extern char **nxt_process_argv;
|
|||||||
NXT_EXPORT extern char ***nxt_process_environ;
|
NXT_EXPORT extern char ***nxt_process_environ;
|
||||||
|
|
||||||
|
|
||||||
typedef uid_t nxt_uid_t;
|
#endif /* _NXT_PROCESS_H_INCLUDED_ */
|
||||||
typedef gid_t nxt_gid_t;
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
const char *user;
|
|
||||||
nxt_uid_t uid;
|
|
||||||
nxt_gid_t base_gid;
|
|
||||||
nxt_uint_t ngroups;
|
|
||||||
nxt_gid_t *gids;
|
|
||||||
} nxt_user_cred_t;
|
|
||||||
|
|
||||||
|
|
||||||
NXT_EXPORT nxt_int_t nxt_user_cred_get(nxt_user_cred_t *uc, const char *group);
|
|
||||||
NXT_EXPORT nxt_int_t nxt_user_cred_set(nxt_user_cred_t *uc);
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* _NXT_UNIX_PROCESS_H_INCLUDED_ */
|
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ static u_char *nxt_process_title_end;
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
nxt_process_arguments(char **orig_argv, char ***orig_envp)
|
nxt_process_arguments(nxt_task_t *task, char **orig_argv, char ***orig_envp)
|
||||||
{
|
{
|
||||||
u_char *p, *end, *argv_end, **argv, **env;
|
u_char *p, *end, *argv_end, **argv, **env;
|
||||||
size_t size, argv_size, environ_size, strings_size;
|
size_t size, argv_size, environ_size, strings_size;
|
||||||
@@ -126,7 +126,7 @@ nxt_process_arguments(char **orig_argv, char ***orig_envp)
|
|||||||
* There is no reason to modify environ if arguments
|
* There is no reason to modify environ if arguments
|
||||||
* and environment are not contiguous.
|
* and environment are not contiguous.
|
||||||
*/
|
*/
|
||||||
nxt_thread_log_debug("arguments and environment are not contiguous");
|
nxt_debug(task, "arguments and environment are not contiguous");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -187,9 +187,10 @@ done:
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
nxt_process_title(const char *title)
|
nxt_process_title(nxt_task_t *task, const char *fmt, ...)
|
||||||
{
|
{
|
||||||
u_char *p, *start, *end;
|
u_char *p, *start, *end;
|
||||||
|
va_list args;
|
||||||
|
|
||||||
start = nxt_process_title_start;
|
start = nxt_process_title_start;
|
||||||
|
|
||||||
@@ -199,7 +200,9 @@ nxt_process_title(const char *title)
|
|||||||
|
|
||||||
end = nxt_process_title_end;
|
end = nxt_process_title_end;
|
||||||
|
|
||||||
p = nxt_sprintf(start, end, "%s", title);
|
va_start(args, fmt);
|
||||||
|
p = nxt_vsprintf(start, end, fmt, args);
|
||||||
|
va_end(args);
|
||||||
|
|
||||||
#if (NXT_SOLARIS)
|
#if (NXT_SOLARIS)
|
||||||
/*
|
/*
|
||||||
@@ -238,7 +241,7 @@ nxt_process_title(const char *title)
|
|||||||
*/
|
*/
|
||||||
nxt_memset(p, '\0', end - p);
|
nxt_memset(p, '\0', end - p);
|
||||||
|
|
||||||
nxt_thread_log_debug("setproctitle: \"%s\"", start);
|
nxt_debug(task, "setproctitle: \"%s\"", start);
|
||||||
}
|
}
|
||||||
|
|
||||||
#else /* !(NXT_SETPROCTITLE_ARGV) */
|
#else /* !(NXT_SETPROCTITLE_ARGV) */
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <nxt_main.h>
|
#include <nxt_main.h>
|
||||||
#include <nxt_cycle.h>
|
#include <nxt_runtime.h>
|
||||||
#include <nxt_application.h>
|
#include <nxt_application.h>
|
||||||
|
|
||||||
|
|
||||||
@@ -45,7 +45,7 @@ static PyObject *nxt_py_input_readline(nxt_py_input_t *self, PyObject *args);
|
|||||||
static PyObject *nxt_py_input_readlines(nxt_py_input_t *self, PyObject *args);
|
static PyObject *nxt_py_input_readlines(nxt_py_input_t *self, PyObject *args);
|
||||||
|
|
||||||
|
|
||||||
extern nxt_int_t nxt_python_wsgi_init(nxt_thread_t *thr, nxt_cycle_t *cycle);
|
extern nxt_int_t nxt_python_wsgi_init(nxt_thread_t *thr, nxt_runtime_t *rt);
|
||||||
|
|
||||||
|
|
||||||
nxt_application_module_t nxt_python_module = {
|
nxt_application_module_t nxt_python_module = {
|
||||||
@@ -130,7 +130,7 @@ static nxt_app_request_t *nxt_app_request;
|
|||||||
|
|
||||||
|
|
||||||
nxt_int_t
|
nxt_int_t
|
||||||
nxt_python_wsgi_init(nxt_thread_t *thr, nxt_cycle_t *cycle)
|
nxt_python_wsgi_init(nxt_thread_t *thr, nxt_runtime_t *rt)
|
||||||
{
|
{
|
||||||
char **argv;
|
char **argv;
|
||||||
u_char *p, *dir;
|
u_char *p, *dir;
|
||||||
@@ -295,7 +295,8 @@ nxt_python_init(nxt_thread_t *thr)
|
|||||||
return NXT_ERROR;
|
return NXT_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
pModule = PyImport_ExecCodeModuleEx((char *) "_wsgi_nginext", co, (char *) script);
|
pModule = PyImport_ExecCodeModuleEx((char *) "_wsgi_nginext", co,
|
||||||
|
(char *) script);
|
||||||
|
|
||||||
Py_XDECREF(co);
|
Py_XDECREF(co);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ nxt_queue_is_empty(queue) \
|
|||||||
*
|
*
|
||||||
* for (lnk = nxt_queue_last(queue);
|
* for (lnk = nxt_queue_last(queue);
|
||||||
* lnk != nxt_queue_head(queue);
|
* lnk != nxt_queue_head(queue);
|
||||||
* lnk = nxt_queue_next(lnk))
|
* lnk = nxt_queue_prev(lnk))
|
||||||
* {
|
* {
|
||||||
* tp = nxt_queue_link_data(lnk, nxt_type_t, link);
|
* tp = nxt_queue_link_data(lnk, nxt_type_t, link);
|
||||||
*/
|
*/
|
||||||
|
|||||||
85
src/nxt_router.c
Normal file
85
src/nxt_router.c
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) Igor Sysoev
|
||||||
|
* Copyright (C) Valentin V. Bartenev
|
||||||
|
* Copyright (C) NGINX, Inc.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <nxt_main.h>
|
||||||
|
#include <nxt_runtime.h>
|
||||||
|
#include <nxt_master_process.h>
|
||||||
|
|
||||||
|
|
||||||
|
static nxt_int_t nxt_router_listen_socket(nxt_task_t *task, nxt_runtime_t *rt);
|
||||||
|
|
||||||
|
|
||||||
|
nxt_int_t
|
||||||
|
nxt_router_start(nxt_task_t *task, nxt_runtime_t *rt)
|
||||||
|
{
|
||||||
|
if (nxt_router_listen_socket(task, rt) != NXT_OK) {
|
||||||
|
return NXT_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NXT_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static nxt_int_t
|
||||||
|
nxt_router_listen_socket(nxt_task_t *task, nxt_runtime_t *rt)
|
||||||
|
{
|
||||||
|
nxt_sockaddr_t *sa;
|
||||||
|
nxt_listen_socket_t *ls;
|
||||||
|
|
||||||
|
sa = nxt_sockaddr_alloc(rt->mem_pool, sizeof(struct sockaddr_in),
|
||||||
|
NXT_INET_ADDR_STR_LEN);
|
||||||
|
if (sa == NULL) {
|
||||||
|
return NXT_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
sa->type = SOCK_STREAM;
|
||||||
|
sa->u.sockaddr_in.sin_family = AF_INET;
|
||||||
|
sa->u.sockaddr_in.sin_port = htons(8000);
|
||||||
|
|
||||||
|
nxt_sockaddr_text(sa);
|
||||||
|
|
||||||
|
ls = nxt_runtime_listen_socket_add(rt, sa);
|
||||||
|
if (ls == NULL) {
|
||||||
|
return NXT_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
ls->read_after_accept = 1;
|
||||||
|
|
||||||
|
ls->flags = NXT_NONBLOCK;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
/* STUB */
|
||||||
|
wq = nxt_mem_zalloc(cf->mem_pool, sizeof(nxt_work_queue_t));
|
||||||
|
if (wq == NULL) {
|
||||||
|
return NXT_ERROR;
|
||||||
|
}
|
||||||
|
nxt_work_queue_name(wq, "listen");
|
||||||
|
/**/
|
||||||
|
|
||||||
|
ls->work_queue = wq;
|
||||||
|
#endif
|
||||||
|
ls->handler = nxt_stream_connection_init;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Connection memory pool chunk size is tunned to
|
||||||
|
* allocate the most data in one mem_pool chunk.
|
||||||
|
*/
|
||||||
|
ls->mem_pool_size = nxt_listen_socket_pool_min_size(ls)
|
||||||
|
+ sizeof(nxt_event_conn_proxy_t)
|
||||||
|
+ sizeof(nxt_event_conn_t)
|
||||||
|
+ 4 * sizeof(nxt_buf_t);
|
||||||
|
|
||||||
|
if (nxt_listen_socket_create(task, ls, 0) != NXT_OK) {
|
||||||
|
return NXT_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nxt_event_conn_listen(task, ls) != NXT_OK) {
|
||||||
|
return NXT_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NXT_OK;
|
||||||
|
}
|
||||||
1499
src/nxt_runtime.c
Normal file
1499
src/nxt_runtime.c
Normal file
File diff suppressed because it is too large
Load Diff
108
src/nxt_runtime.h
Normal file
108
src/nxt_runtime.h
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) Igor Sysoev
|
||||||
|
* Copyright (C) Valentin V. Bartenev
|
||||||
|
* Copyright (C) NGINX, Inc.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _NXT_RUNTIME_H_INCLUDED_
|
||||||
|
#define _NXT_RUNTIME_H_INCLUDED_
|
||||||
|
|
||||||
|
|
||||||
|
typedef void (*nxt_runtime_cont_t)(nxt_task_t *task);
|
||||||
|
|
||||||
|
|
||||||
|
struct nxt_runtime_s {
|
||||||
|
nxt_mem_pool_t *mem_pool;
|
||||||
|
|
||||||
|
nxt_array_t *inherited_sockets; /* of nxt_listen_socket_t */
|
||||||
|
nxt_array_t *listen_sockets; /* of nxt_listen_socket_t */
|
||||||
|
|
||||||
|
nxt_array_t *services; /* of nxt_service_t */
|
||||||
|
nxt_array_t *engines; /* of nxt_event_engine_t */
|
||||||
|
|
||||||
|
nxt_runtime_cont_t start;
|
||||||
|
|
||||||
|
nxt_str_t *conf_prefix;
|
||||||
|
nxt_str_t *prefix;
|
||||||
|
|
||||||
|
nxt_str_t hostname;
|
||||||
|
|
||||||
|
nxt_file_name_t *pid_file;
|
||||||
|
|
||||||
|
#if (NXT_THREADS)
|
||||||
|
nxt_array_t *thread_pools; /* of nxt_thread_pool_t */
|
||||||
|
nxt_runtime_cont_t continuation;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
nxt_array_t *processes; /* of nxt_process_t */
|
||||||
|
|
||||||
|
nxt_list_t *log_files; /* of nxt_file_t */
|
||||||
|
|
||||||
|
uint32_t last_engine_id;
|
||||||
|
|
||||||
|
nxt_process_type_t type;
|
||||||
|
|
||||||
|
nxt_timer_t timer;
|
||||||
|
|
||||||
|
uint8_t daemon;
|
||||||
|
uint8_t batch;
|
||||||
|
uint8_t master_process;
|
||||||
|
const char *engine;
|
||||||
|
uint32_t engine_connections;
|
||||||
|
uint32_t worker_processes;
|
||||||
|
uint32_t auxiliary_threads;
|
||||||
|
nxt_user_cred_t user_cred;
|
||||||
|
const char *group;
|
||||||
|
const char *pid;
|
||||||
|
const char *error_log;
|
||||||
|
|
||||||
|
nxt_sockaddr_t *controller_listen;
|
||||||
|
nxt_listen_socket_t *controller_socket;
|
||||||
|
nxt_str_t upstream;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
typedef nxt_int_t (*nxt_module_init_t)(nxt_thread_t *thr, nxt_runtime_t *rt);
|
||||||
|
|
||||||
|
|
||||||
|
nxt_int_t nxt_runtime_create(nxt_task_t *task);
|
||||||
|
void nxt_runtime_quit(nxt_task_t *task);
|
||||||
|
|
||||||
|
void nxt_runtime_event_engine_free(nxt_runtime_t *rt);
|
||||||
|
|
||||||
|
#if (NXT_THREADS)
|
||||||
|
nxt_int_t nxt_runtime_thread_pool_create(nxt_thread_t *thr, nxt_runtime_t *rt,
|
||||||
|
nxt_uint_t max_threads, nxt_nsec_t timeout);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
nxt_process_t *nxt_runtime_new_process(nxt_runtime_t *rt);
|
||||||
|
|
||||||
|
/* STUB */
|
||||||
|
nxt_int_t nxt_runtime_controller_socket(nxt_task_t *task, nxt_runtime_t *rt);
|
||||||
|
|
||||||
|
nxt_str_t *nxt_current_directory(nxt_mem_pool_t *mp);
|
||||||
|
|
||||||
|
nxt_listen_socket_t *nxt_runtime_listen_socket_add(nxt_runtime_t *rt,
|
||||||
|
nxt_sockaddr_t *sa);
|
||||||
|
nxt_int_t nxt_runtime_listen_sockets_create(nxt_task_t *task,
|
||||||
|
nxt_runtime_t *rt);
|
||||||
|
nxt_int_t nxt_runtime_listen_sockets_enable(nxt_task_t *task,
|
||||||
|
nxt_runtime_t *rt);
|
||||||
|
nxt_file_t *nxt_runtime_log_file_add(nxt_runtime_t *rt, nxt_str_t *name);
|
||||||
|
|
||||||
|
/* STUB */
|
||||||
|
void nxt_cdecl nxt_log_time_handler(nxt_uint_t level, nxt_log_t *log,
|
||||||
|
const char *fmt, ...);
|
||||||
|
|
||||||
|
void nxt_stream_connection_init(nxt_task_t *task, void *obj, void *data);
|
||||||
|
nxt_int_t nxt_app_start(nxt_task_t *task, nxt_runtime_t *rt);
|
||||||
|
|
||||||
|
|
||||||
|
extern nxt_module_init_t nxt_init_modules[];
|
||||||
|
extern nxt_uint_t nxt_init_modules_n;
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* _NXT_RUNTIME_H_INCLIDED_ */
|
||||||
@@ -8,11 +8,11 @@
|
|||||||
#define _NXT_SIGNAL_H_INCLUDED_
|
#define _NXT_SIGNAL_H_INCLUDED_
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
struct nxt_sig_event_s {
|
||||||
int signo;
|
int signo;
|
||||||
nxt_work_handler_t handler;
|
nxt_work_handler_t handler;
|
||||||
const char *name;
|
const char *name;
|
||||||
} nxt_sig_event_t;
|
};
|
||||||
|
|
||||||
#define nxt_event_signal(sig, handler) \
|
#define nxt_event_signal(sig, handler) \
|
||||||
{ sig, handler, #sig }
|
{ sig, handler, #sig }
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <nxt_main.h>
|
#include <nxt_main.h>
|
||||||
#include <nxt_cycle.h>
|
#include <nxt_runtime.h>
|
||||||
|
|
||||||
|
|
||||||
static void nxt_stream_connection_peer(nxt_task_t *task,
|
static void nxt_stream_connection_peer(nxt_task_t *task,
|
||||||
@@ -17,7 +17,7 @@ static void nxt_stream_connection_close(nxt_task_t *task, void *obj,
|
|||||||
void
|
void
|
||||||
nxt_stream_connection_init(nxt_task_t *task, void *obj, void *data)
|
nxt_stream_connection_init(nxt_task_t *task, void *obj, void *data)
|
||||||
{
|
{
|
||||||
nxt_cycle_t *cycle;
|
nxt_runtime_t *rt;
|
||||||
nxt_event_conn_t *c;
|
nxt_event_conn_t *c;
|
||||||
nxt_upstream_peer_t *up;
|
nxt_upstream_peer_t *up;
|
||||||
|
|
||||||
@@ -32,10 +32,10 @@ nxt_stream_connection_init(nxt_task_t *task, void *obj, void *data)
|
|||||||
|
|
||||||
up->data = c;
|
up->data = c;
|
||||||
|
|
||||||
cycle = nxt_thread_cycle();
|
rt = task->thread->runtime;
|
||||||
|
|
||||||
if (cycle->upstream.length != 0) {
|
if (rt->upstream.length != 0) {
|
||||||
up->addr = cycle->upstream;
|
up->addr = rt->upstream;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
nxt_str_set(&up->addr, "127.0.0.1:8080");
|
nxt_str_set(&up->addr, "127.0.0.1:8080");
|
||||||
|
|||||||
@@ -178,6 +178,7 @@ struct nxt_thread_s {
|
|||||||
|
|
||||||
nxt_thread_time_t time;
|
nxt_thread_time_t time;
|
||||||
|
|
||||||
|
nxt_runtime_t *runtime;
|
||||||
nxt_event_engine_t *engine;
|
nxt_event_engine_t *engine;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -110,7 +110,7 @@ nxt_upstream_round_robin_create(nxt_task_t *task, void *obj, void *data)
|
|||||||
/* STUB */
|
/* STUB */
|
||||||
up->sockaddr = peer[0].sockaddr;
|
up->sockaddr = peer[0].sockaddr;
|
||||||
|
|
||||||
nxt_job_destroy(jbs);
|
nxt_job_destroy(task, jbs);
|
||||||
up->ready_handler(task, up);
|
up->ready_handler(task, up);
|
||||||
|
|
||||||
//nxt_upstream_round_robin_get_peer(up);
|
//nxt_upstream_round_robin_get_peer(up);
|
||||||
@@ -118,7 +118,7 @@ nxt_upstream_round_robin_create(nxt_task_t *task, void *obj, void *data)
|
|||||||
|
|
||||||
fail:
|
fail:
|
||||||
|
|
||||||
nxt_job_destroy(jbs);
|
nxt_job_destroy(task, jbs);
|
||||||
|
|
||||||
up->ready_handler(task, up);
|
up->ready_handler(task, up);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ struct nxt_task_s {
|
|||||||
* A work handler with just the obj and data arguments instead
|
* A work handler with just the obj and data arguments instead
|
||||||
* of pointer to a possibly large a work struct allows to call
|
* of pointer to a possibly large a work struct allows to call
|
||||||
* the handler not only via a work queue but also directly.
|
* the handler not only via a work queue but also directly.
|
||||||
* The only obj argument is enough for the most cases expect the
|
* The only obj argument is enough for the most cases except the
|
||||||
* source filters, so the data argument has been introduced and
|
* source filters, so the data argument has been introduced and
|
||||||
* is used where appropriate.
|
* is used where appropriate.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <nxt_main.h>
|
#include <nxt_main.h>
|
||||||
#include <nxt_cycle.h>
|
#include <nxt_runtime.h>
|
||||||
#include <nxt_port.h>
|
#include <nxt_port.h>
|
||||||
#include <nxt_master_process.h>
|
#include <nxt_master_process.h>
|
||||||
|
|
||||||
@@ -21,7 +21,7 @@ static void nxt_worker_process_sigquit_handler(nxt_task_t *task, void *obj,
|
|||||||
void *data);
|
void *data);
|
||||||
|
|
||||||
|
|
||||||
static nxt_port_handler_t nxt_worker_process_port_handlers[] = {
|
nxt_port_handler_t nxt_worker_process_port_handlers[] = {
|
||||||
nxt_worker_process_quit_handler,
|
nxt_worker_process_quit_handler,
|
||||||
nxt_port_new_port_handler,
|
nxt_port_new_port_handler,
|
||||||
nxt_port_change_log_file_handler,
|
nxt_port_change_log_file_handler,
|
||||||
@@ -29,112 +29,29 @@ static nxt_port_handler_t nxt_worker_process_port_handlers[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static const nxt_sig_event_t nxt_worker_process_signals[] = {
|
const nxt_sig_event_t nxt_worker_process_signals[] = {
|
||||||
nxt_event_signal(SIGHUP, nxt_worker_process_signal_handler),
|
nxt_event_signal(SIGHUP, nxt_worker_process_signal_handler),
|
||||||
nxt_event_signal(SIGINT, nxt_worker_process_sigterm_handler),
|
nxt_event_signal(SIGINT, nxt_worker_process_sigterm_handler),
|
||||||
nxt_event_signal(SIGQUIT, 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(SIGTERM, nxt_worker_process_sigquit_handler),
|
||||||
nxt_event_signal(SIGCHLD, nxt_worker_process_signal_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(SIGUSR1, nxt_worker_process_signal_handler),
|
nxt_event_signal(SIGUSR2, nxt_worker_process_signal_handler),
|
||||||
nxt_event_signal_end,
|
nxt_event_signal_end,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
nxt_worker_process_start(void *data)
|
|
||||||
{
|
|
||||||
nxt_int_t n;
|
|
||||||
nxt_port_t *port;
|
|
||||||
nxt_cycle_t *cycle;
|
|
||||||
nxt_thread_t *thr;
|
|
||||||
const nxt_event_interface_t *interface;
|
|
||||||
|
|
||||||
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("nginext: 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;
|
|
||||||
|
|
||||||
interface = nxt_service_get(cycle->services, "engine", cycle->engine);
|
|
||||||
if (interface == NULL) {
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nxt_event_engine_change(thr, &nxt_main_task, interface, cycle->batch) != NXT_OK) {
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nxt_cycle_listen_sockets_enable(&thr->engine->task, cycle) != NXT_OK) {
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
port = cycle->ports->elts;
|
|
||||||
|
|
||||||
/* A master process port. */
|
|
||||||
nxt_port_read_close(&port[0]);
|
|
||||||
nxt_port_write_enable(&nxt_main_task, &port[0]);
|
|
||||||
|
|
||||||
/* A worker process port. */
|
|
||||||
nxt_port_create(thr, &port[cycle->current_process],
|
|
||||||
nxt_worker_process_port_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
|
static void
|
||||||
nxt_worker_process_quit(nxt_task_t *task)
|
nxt_worker_process_quit(nxt_task_t *task)
|
||||||
{
|
{
|
||||||
nxt_uint_t n;
|
nxt_uint_t n;
|
||||||
nxt_cycle_t *cycle;
|
|
||||||
nxt_queue_t *listen;
|
nxt_queue_t *listen;
|
||||||
|
nxt_runtime_t *rt;
|
||||||
nxt_queue_link_t *link, *next;
|
nxt_queue_link_t *link, *next;
|
||||||
nxt_listen_socket_t *ls;
|
nxt_listen_socket_t *ls;
|
||||||
nxt_event_conn_listen_t *cls;
|
nxt_event_conn_listen_t *cls;
|
||||||
|
|
||||||
cycle = nxt_thread_cycle();
|
rt = task->thread->runtime;
|
||||||
|
|
||||||
nxt_debug(task, "close listen connections");
|
nxt_debug(task, "close listen connections");
|
||||||
|
|
||||||
@@ -151,10 +68,10 @@ nxt_worker_process_quit(nxt_task_t *task)
|
|||||||
nxt_fd_event_close(task->thread->engine, &cls->socket);
|
nxt_fd_event_close(task->thread->engine, &cls->socket);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cycle->listen_sockets != NULL) {
|
if (rt->listen_sockets != NULL) {
|
||||||
|
|
||||||
ls = cycle->listen_sockets->elts;
|
ls = rt->listen_sockets->elts;
|
||||||
n = cycle->listen_sockets->nelts;
|
n = rt->listen_sockets->nelts;
|
||||||
|
|
||||||
while (n != 0) {
|
while (n != 0) {
|
||||||
nxt_socket_close(task, ls->socket);
|
nxt_socket_close(task, ls->socket);
|
||||||
@@ -164,10 +81,10 @@ nxt_worker_process_quit(nxt_task_t *task)
|
|||||||
n--;
|
n--;
|
||||||
}
|
}
|
||||||
|
|
||||||
cycle->listen_sockets->nelts = 0;
|
rt->listen_sockets->nelts = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
nxt_cycle_quit(task, cycle);
|
nxt_runtime_quit(task);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -194,7 +111,7 @@ nxt_worker_process_sigterm_handler(nxt_task_t *task, void *obj, void *data)
|
|||||||
|
|
||||||
/* A fast exit. */
|
/* A fast exit. */
|
||||||
|
|
||||||
nxt_cycle_quit(task, NULL);
|
nxt_runtime_quit(task);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user