120Sigor@sysoev.ru 220Sigor@sysoev.ru /* 320Sigor@sysoev.ru * Copyright (C) Igor Sysoev 420Sigor@sysoev.ru * Copyright (C) Valentin V. Bartenev 520Sigor@sysoev.ru * Copyright (C) NGINX, Inc. 620Sigor@sysoev.ru */ 720Sigor@sysoev.ru 853Sigor@sysoev.ru #include <nxt_router.h> 9115Sigor@sysoev.ru #include <nxt_conf.h> 1020Sigor@sysoev.ru 1120Sigor@sysoev.ru 12115Sigor@sysoev.ru typedef struct { 13318Smax.romanov@nginx.com nxt_str_t type; 14318Smax.romanov@nginx.com uint32_t workers; 15318Smax.romanov@nginx.com nxt_msec_t timeout; 16318Smax.romanov@nginx.com uint32_t requests; 17318Smax.romanov@nginx.com nxt_conf_value_t *limits_value; 18133Sigor@sysoev.ru } nxt_router_app_conf_t; 19133Sigor@sysoev.ru 20133Sigor@sysoev.ru 21133Sigor@sysoev.ru typedef struct { 22133Sigor@sysoev.ru nxt_str_t application; 23115Sigor@sysoev.ru } nxt_router_listener_conf_t; 24115Sigor@sysoev.ru 25115Sigor@sysoev.ru 26167Smax.romanov@nginx.com typedef struct nxt_req_app_link_s nxt_req_app_link_t; 27141Smax.romanov@nginx.com 28141Smax.romanov@nginx.com 29318Smax.romanov@nginx.com typedef struct { 30318Smax.romanov@nginx.com uint32_t stream; 31318Smax.romanov@nginx.com nxt_conn_t *conn; 32*343Smax.romanov@nginx.com nxt_app_t *app; 33318Smax.romanov@nginx.com nxt_port_t *app_port; 34318Smax.romanov@nginx.com nxt_req_app_link_t *ra; 35318Smax.romanov@nginx.com 36318Smax.romanov@nginx.com nxt_queue_link_t link; /* for nxt_conn_t.requests */ 37318Smax.romanov@nginx.com } nxt_req_conn_link_t; 38318Smax.romanov@nginx.com 39318Smax.romanov@nginx.com 40167Smax.romanov@nginx.com struct nxt_req_app_link_s { 41318Smax.romanov@nginx.com uint32_t stream; 42167Smax.romanov@nginx.com nxt_port_t *app_port; 43318Smax.romanov@nginx.com nxt_pid_t app_pid; 44167Smax.romanov@nginx.com nxt_port_t *reply_port; 45167Smax.romanov@nginx.com nxt_app_parse_ctx_t *ap; 46167Smax.romanov@nginx.com nxt_req_conn_link_t *rc; 47167Smax.romanov@nginx.com 48167Smax.romanov@nginx.com nxt_queue_link_t link; /* for nxt_app_t.requests */ 49167Smax.romanov@nginx.com 50167Smax.romanov@nginx.com nxt_mp_t *mem_pool; 51167Smax.romanov@nginx.com nxt_work_t work; 52167Smax.romanov@nginx.com }; 53167Smax.romanov@nginx.com 54167Smax.romanov@nginx.com 55198Sigor@sysoev.ru typedef struct { 56198Sigor@sysoev.ru nxt_socket_conf_t *socket_conf; 57198Sigor@sysoev.ru nxt_router_temp_conf_t *temp_conf; 58198Sigor@sysoev.ru } nxt_socket_rpc_t; 59198Sigor@sysoev.ru 60198Sigor@sysoev.ru 61318Smax.romanov@nginx.com typedef struct { 62318Smax.romanov@nginx.com nxt_mp_t *mem_pool; 63318Smax.romanov@nginx.com nxt_port_recv_msg_t msg; 64318Smax.romanov@nginx.com nxt_work_t work; 65318Smax.romanov@nginx.com } nxt_remove_pid_msg_t; 66318Smax.romanov@nginx.com 67318Smax.romanov@nginx.com 68*343Smax.romanov@nginx.com static nxt_int_t nxt_router_start_worker(nxt_task_t *task, nxt_app_t *app); 69*343Smax.romanov@nginx.com 70318Smax.romanov@nginx.com static void nxt_router_worker_remove_pid_handler(nxt_task_t *task, void *obj, 71318Smax.romanov@nginx.com void *data); 72318Smax.romanov@nginx.com static void nxt_router_worker_remove_pid_done(nxt_task_t *task, void *obj, 73318Smax.romanov@nginx.com void *data); 74318Smax.romanov@nginx.com 75139Sigor@sysoev.ru static nxt_router_temp_conf_t *nxt_router_temp_conf(nxt_task_t *task); 76198Sigor@sysoev.ru static void nxt_router_conf_apply(nxt_task_t *task, void *obj, void *data); 77198Sigor@sysoev.ru static void nxt_router_conf_ready(nxt_task_t *task, 78139Sigor@sysoev.ru nxt_router_temp_conf_t *tmcf); 79139Sigor@sysoev.ru static void nxt_router_conf_error(nxt_task_t *task, 80139Sigor@sysoev.ru nxt_router_temp_conf_t *tmcf); 81139Sigor@sysoev.ru static void nxt_router_conf_send(nxt_task_t *task, 82193Smax.romanov@nginx.com nxt_router_temp_conf_t *tmcf, nxt_port_msg_type_t type); 8353Sigor@sysoev.ru static void nxt_router_listen_sockets_sort(nxt_router_t *router, 8453Sigor@sysoev.ru nxt_router_temp_conf_t *tmcf); 8553Sigor@sysoev.ru 86115Sigor@sysoev.ru static nxt_int_t nxt_router_conf_create(nxt_task_t *task, 87115Sigor@sysoev.ru nxt_router_temp_conf_t *tmcf, u_char *start, u_char *end); 88133Sigor@sysoev.ru static nxt_app_t *nxt_router_app_find(nxt_queue_t *queue, nxt_str_t *name); 89133Sigor@sysoev.ru static nxt_app_t *nxt_router_listener_application(nxt_router_temp_conf_t *tmcf, 90133Sigor@sysoev.ru nxt_str_t *name); 91198Sigor@sysoev.ru static void nxt_router_listen_socket_rpc_create(nxt_task_t *task, 92198Sigor@sysoev.ru nxt_router_temp_conf_t *tmcf, nxt_socket_conf_t *skcf); 93198Sigor@sysoev.ru static void nxt_router_listen_socket_ready(nxt_task_t *task, 94198Sigor@sysoev.ru nxt_port_recv_msg_t *msg, void *data); 95198Sigor@sysoev.ru static void nxt_router_listen_socket_error(nxt_task_t *task, 96198Sigor@sysoev.ru nxt_port_recv_msg_t *msg, void *data); 9765Sigor@sysoev.ru static nxt_socket_conf_t *nxt_router_socket_conf(nxt_task_t *task, nxt_mp_t *mp, 9865Sigor@sysoev.ru nxt_sockaddr_t *sa); 9953Sigor@sysoev.ru 10053Sigor@sysoev.ru static nxt_int_t nxt_router_engines_create(nxt_task_t *task, 10153Sigor@sysoev.ru nxt_router_t *router, nxt_router_temp_conf_t *tmcf, 10253Sigor@sysoev.ru const nxt_event_interface_t *interface); 103115Sigor@sysoev.ru static nxt_int_t nxt_router_engine_conf_create(nxt_router_temp_conf_t *tmcf, 104115Sigor@sysoev.ru nxt_router_engine_conf_t *recf); 105115Sigor@sysoev.ru static nxt_int_t nxt_router_engine_conf_update(nxt_router_temp_conf_t *tmcf, 106115Sigor@sysoev.ru nxt_router_engine_conf_t *recf); 107115Sigor@sysoev.ru static nxt_int_t nxt_router_engine_conf_delete(nxt_router_temp_conf_t *tmcf, 108115Sigor@sysoev.ru nxt_router_engine_conf_t *recf); 109115Sigor@sysoev.ru static void nxt_router_engine_socket_count(nxt_queue_t *sockets); 110154Sigor@sysoev.ru static nxt_int_t nxt_router_engine_joints_create(nxt_router_temp_conf_t *tmcf, 111154Sigor@sysoev.ru nxt_router_engine_conf_t *recf, nxt_queue_t *sockets, 112154Sigor@sysoev.ru nxt_work_handler_t handler); 113313Sigor@sysoev.ru static nxt_int_t nxt_router_engine_quit(nxt_router_temp_conf_t *tmcf, 114313Sigor@sysoev.ru nxt_router_engine_conf_t *recf); 115139Sigor@sysoev.ru static nxt_int_t nxt_router_engine_joints_delete(nxt_router_temp_conf_t *tmcf, 116139Sigor@sysoev.ru nxt_router_engine_conf_t *recf, nxt_queue_t *sockets); 11753Sigor@sysoev.ru 11853Sigor@sysoev.ru static nxt_int_t nxt_router_threads_create(nxt_task_t *task, nxt_runtime_t *rt, 11953Sigor@sysoev.ru nxt_router_temp_conf_t *tmcf); 12053Sigor@sysoev.ru static nxt_int_t nxt_router_thread_create(nxt_task_t *task, nxt_runtime_t *rt, 12153Sigor@sysoev.ru nxt_event_engine_t *engine); 122*343Smax.romanov@nginx.com static void nxt_router_apps_sort(nxt_task_t *task, nxt_router_t *router, 123133Sigor@sysoev.ru nxt_router_temp_conf_t *tmcf); 12453Sigor@sysoev.ru 125315Sigor@sysoev.ru static void nxt_router_engines_post(nxt_router_t *router, 126315Sigor@sysoev.ru nxt_router_temp_conf_t *tmcf); 127315Sigor@sysoev.ru static void nxt_router_engine_post(nxt_event_engine_t *engine, 128315Sigor@sysoev.ru nxt_work_t *jobs); 12953Sigor@sysoev.ru 13053Sigor@sysoev.ru static void nxt_router_thread_start(void *data); 13153Sigor@sysoev.ru static void nxt_router_listen_socket_create(nxt_task_t *task, void *obj, 13253Sigor@sysoev.ru void *data); 13353Sigor@sysoev.ru static void nxt_router_listen_socket_update(nxt_task_t *task, void *obj, 13453Sigor@sysoev.ru void *data); 13553Sigor@sysoev.ru static void nxt_router_listen_socket_delete(nxt_task_t *task, void *obj, 13653Sigor@sysoev.ru void *data); 137313Sigor@sysoev.ru static void nxt_router_worker_thread_quit(nxt_task_t *task, void *obj, 138313Sigor@sysoev.ru void *data); 13953Sigor@sysoev.ru static void nxt_router_listen_socket_close(nxt_task_t *task, void *obj, 14053Sigor@sysoev.ru void *data); 14153Sigor@sysoev.ru static void nxt_router_listen_socket_release(nxt_task_t *task, 14253Sigor@sysoev.ru nxt_socket_conf_joint_t *joint); 14353Sigor@sysoev.ru static void nxt_router_thread_exit_handler(nxt_task_t *task, void *obj, 14453Sigor@sysoev.ru void *data); 14553Sigor@sysoev.ru static void nxt_router_conf_release(nxt_task_t *task, 14653Sigor@sysoev.ru nxt_socket_conf_joint_t *joint); 14753Sigor@sysoev.ru 148*343Smax.romanov@nginx.com static void nxt_router_app_port_ready(nxt_task_t *task, 149*343Smax.romanov@nginx.com nxt_port_recv_msg_t *msg, void *data); 150*343Smax.romanov@nginx.com static void nxt_router_app_port_error(nxt_task_t *task, 151*343Smax.romanov@nginx.com nxt_port_recv_msg_t *msg, void *data); 152*343Smax.romanov@nginx.com 153*343Smax.romanov@nginx.com static nxt_port_t * nxt_router_app_get_idle_port(nxt_app_t *app); 154*343Smax.romanov@nginx.com static void nxt_router_app_port_release(nxt_task_t *task, nxt_port_t *port, 155*343Smax.romanov@nginx.com uint32_t request_failed, uint32_t got_response); 156141Smax.romanov@nginx.com 15753Sigor@sysoev.ru static void nxt_router_conn_init(nxt_task_t *task, void *obj, void *data); 15853Sigor@sysoev.ru static void nxt_router_conn_http_header_parse(nxt_task_t *task, void *obj, 15953Sigor@sysoev.ru void *data); 160206Smax.romanov@nginx.com static void nxt_router_conn_http_body_read(nxt_task_t *task, void *obj, 161206Smax.romanov@nginx.com void *data); 16288Smax.romanov@nginx.com static void nxt_router_process_http_request(nxt_task_t *task, 16388Smax.romanov@nginx.com nxt_conn_t *c, nxt_app_parse_ctx_t *ap); 164141Smax.romanov@nginx.com static void nxt_router_process_http_request_mp(nxt_task_t *task, 165*343Smax.romanov@nginx.com nxt_req_app_link_t *ra); 166216Sigor@sysoev.ru static nxt_int_t nxt_python_prepare_msg(nxt_task_t *task, nxt_app_request_t *r, 167216Sigor@sysoev.ru nxt_app_wmsg_t *wmsg); 168216Sigor@sysoev.ru static nxt_int_t nxt_php_prepare_msg(nxt_task_t *task, nxt_app_request_t *r, 169216Sigor@sysoev.ru nxt_app_wmsg_t *wmsg); 170216Sigor@sysoev.ru static nxt_int_t nxt_go_prepare_msg(nxt_task_t *task, nxt_app_request_t *r, 171216Sigor@sysoev.ru nxt_app_wmsg_t *wmsg); 17288Smax.romanov@nginx.com static void nxt_router_conn_ready(nxt_task_t *task, void *obj, void *data); 17353Sigor@sysoev.ru static void nxt_router_conn_close(nxt_task_t *task, void *obj, void *data); 17453Sigor@sysoev.ru static void nxt_router_conn_free(nxt_task_t *task, void *obj, void *data); 17553Sigor@sysoev.ru static void nxt_router_conn_error(nxt_task_t *task, void *obj, void *data); 17653Sigor@sysoev.ru static void nxt_router_conn_timeout(nxt_task_t *task, void *obj, void *data); 177318Smax.romanov@nginx.com static void nxt_router_app_timeout(nxt_task_t *task, void *obj, void *data); 17862Sigor@sysoev.ru static nxt_msec_t nxt_router_conn_timeout_value(nxt_conn_t *c, uintptr_t data); 17920Sigor@sysoev.ru 180141Smax.romanov@nginx.com static void nxt_router_gen_error(nxt_task_t *task, nxt_conn_t *c, int code, 181141Smax.romanov@nginx.com const char* fmt, ...); 182141Smax.romanov@nginx.com 183119Smax.romanov@nginx.com static nxt_router_t *nxt_router; 18420Sigor@sysoev.ru 185216Sigor@sysoev.ru 186216Sigor@sysoev.ru static nxt_app_prepare_msg_t nxt_app_prepare_msg[] = { 187216Sigor@sysoev.ru nxt_python_prepare_msg, 188216Sigor@sysoev.ru nxt_php_prepare_msg, 189216Sigor@sysoev.ru nxt_go_prepare_msg, 190216Sigor@sysoev.ru }; 191216Sigor@sysoev.ru 192216Sigor@sysoev.ru 19320Sigor@sysoev.ru nxt_int_t 194141Smax.romanov@nginx.com nxt_router_start(nxt_task_t *task, void *data) 19520Sigor@sysoev.ru { 196141Smax.romanov@nginx.com nxt_int_t ret; 197141Smax.romanov@nginx.com nxt_router_t *router; 198141Smax.romanov@nginx.com nxt_runtime_t *rt; 199141Smax.romanov@nginx.com 200141Smax.romanov@nginx.com rt = task->thread->runtime; 20153Sigor@sysoev.ru 20288Smax.romanov@nginx.com ret = nxt_app_http_init(task, rt); 20388Smax.romanov@nginx.com if (nxt_slow_path(ret != NXT_OK)) { 20488Smax.romanov@nginx.com return ret; 20588Smax.romanov@nginx.com } 20688Smax.romanov@nginx.com 20753Sigor@sysoev.ru router = nxt_zalloc(sizeof(nxt_router_t)); 20853Sigor@sysoev.ru if (nxt_slow_path(router == NULL)) { 20953Sigor@sysoev.ru return NXT_ERROR; 21053Sigor@sysoev.ru } 21153Sigor@sysoev.ru 21253Sigor@sysoev.ru nxt_queue_init(&router->engines); 21353Sigor@sysoev.ru nxt_queue_init(&router->sockets); 214133Sigor@sysoev.ru nxt_queue_init(&router->apps); 21553Sigor@sysoev.ru 216119Smax.romanov@nginx.com nxt_router = router; 217119Smax.romanov@nginx.com 218115Sigor@sysoev.ru return NXT_OK; 219115Sigor@sysoev.ru } 220115Sigor@sysoev.ru 221115Sigor@sysoev.ru 222*343Smax.romanov@nginx.com static void 223*343Smax.romanov@nginx.com nxt_router_start_worker_handler(nxt_task_t *task, nxt_port_t *port, void *data) 224167Smax.romanov@nginx.com { 225*343Smax.romanov@nginx.com size_t size; 226*343Smax.romanov@nginx.com uint32_t stream; 227*343Smax.romanov@nginx.com nxt_app_t *app; 228*343Smax.romanov@nginx.com nxt_buf_t *b; 229*343Smax.romanov@nginx.com nxt_port_t *main_port; 230*343Smax.romanov@nginx.com nxt_runtime_t *rt; 231*343Smax.romanov@nginx.com 232*343Smax.romanov@nginx.com app = data; 233167Smax.romanov@nginx.com 234167Smax.romanov@nginx.com rt = task->thread->runtime; 235240Sigor@sysoev.ru main_port = rt->port_by_type[NXT_PROCESS_MAIN]; 236167Smax.romanov@nginx.com 237*343Smax.romanov@nginx.com nxt_debug(task, "app '%V' %p start worker", &app->name, app); 238*343Smax.romanov@nginx.com 239*343Smax.romanov@nginx.com size = app->name.length + 1 + app->conf.length; 240*343Smax.romanov@nginx.com 241*343Smax.romanov@nginx.com b = nxt_buf_mem_ts_alloc(task, task->thread->engine->mem_pool, size); 242*343Smax.romanov@nginx.com 243*343Smax.romanov@nginx.com if (nxt_slow_path(b == NULL)) { 244*343Smax.romanov@nginx.com goto failed; 245167Smax.romanov@nginx.com } 246167Smax.romanov@nginx.com 247*343Smax.romanov@nginx.com nxt_buf_cpystr(b, &app->name); 248*343Smax.romanov@nginx.com *b->mem.free++ = '\0'; 249*343Smax.romanov@nginx.com nxt_buf_cpystr(b, &app->conf); 250*343Smax.romanov@nginx.com 251*343Smax.romanov@nginx.com stream = nxt_port_rpc_register_handler(task, port, 252*343Smax.romanov@nginx.com nxt_router_app_port_ready, 253*343Smax.romanov@nginx.com nxt_router_app_port_error, 254*343Smax.romanov@nginx.com -1, app); 255*343Smax.romanov@nginx.com 256*343Smax.romanov@nginx.com if (nxt_slow_path(stream == 0)) { 257*343Smax.romanov@nginx.com nxt_mp_release(b->data, b); 258*343Smax.romanov@nginx.com 259*343Smax.romanov@nginx.com goto failed; 260*343Smax.romanov@nginx.com } 261*343Smax.romanov@nginx.com 262*343Smax.romanov@nginx.com nxt_port_socket_write(task, main_port, NXT_PORT_MSG_START_WORKER, -1, 263*343Smax.romanov@nginx.com stream, port->id, b); 264*343Smax.romanov@nginx.com 265*343Smax.romanov@nginx.com return; 266*343Smax.romanov@nginx.com 267*343Smax.romanov@nginx.com failed: 268*343Smax.romanov@nginx.com 269*343Smax.romanov@nginx.com nxt_thread_mutex_lock(&app->mutex); 270*343Smax.romanov@nginx.com 271*343Smax.romanov@nginx.com app->pending_workers--; 272*343Smax.romanov@nginx.com 273*343Smax.romanov@nginx.com nxt_thread_mutex_unlock(&app->mutex); 274*343Smax.romanov@nginx.com 275*343Smax.romanov@nginx.com nxt_router_app_use(task, app, -1); 276167Smax.romanov@nginx.com } 277167Smax.romanov@nginx.com 278167Smax.romanov@nginx.com 279*343Smax.romanov@nginx.com static nxt_int_t 280*343Smax.romanov@nginx.com nxt_router_start_worker(nxt_task_t *task, nxt_app_t *app) 281141Smax.romanov@nginx.com { 282*343Smax.romanov@nginx.com nxt_int_t res; 283*343Smax.romanov@nginx.com nxt_port_t *router_port; 284*343Smax.romanov@nginx.com nxt_runtime_t *rt; 285*343Smax.romanov@nginx.com 286*343Smax.romanov@nginx.com rt = task->thread->runtime; 287*343Smax.romanov@nginx.com router_port = rt->port_by_type[NXT_PROCESS_ROUTER]; 288*343Smax.romanov@nginx.com 289*343Smax.romanov@nginx.com nxt_router_app_use(task, app, 1); 290*343Smax.romanov@nginx.com 291*343Smax.romanov@nginx.com res = nxt_port_post(task, router_port, nxt_router_start_worker_handler, 292*343Smax.romanov@nginx.com app); 293*343Smax.romanov@nginx.com 294*343Smax.romanov@nginx.com if (res == NXT_OK) { 295*343Smax.romanov@nginx.com return res; 296318Smax.romanov@nginx.com } 297318Smax.romanov@nginx.com 298*343Smax.romanov@nginx.com nxt_thread_mutex_lock(&app->mutex); 299*343Smax.romanov@nginx.com 300*343Smax.romanov@nginx.com app->pending_workers--; 301*343Smax.romanov@nginx.com 302*343Smax.romanov@nginx.com nxt_thread_mutex_unlock(&app->mutex); 303*343Smax.romanov@nginx.com 304*343Smax.romanov@nginx.com nxt_router_app_use(task, app, -1); 305*343Smax.romanov@nginx.com 306*343Smax.romanov@nginx.com return NXT_ERROR; 307318Smax.romanov@nginx.com } 308318Smax.romanov@nginx.com 309318Smax.romanov@nginx.com 310167Smax.romanov@nginx.com static nxt_req_app_link_t * 311167Smax.romanov@nginx.com nxt_router_ra_create(nxt_task_t *task, nxt_req_conn_link_t *rc) 312167Smax.romanov@nginx.com { 313167Smax.romanov@nginx.com nxt_mp_t *mp; 314318Smax.romanov@nginx.com nxt_event_engine_t *engine; 315167Smax.romanov@nginx.com nxt_req_app_link_t *ra; 316167Smax.romanov@nginx.com 317167Smax.romanov@nginx.com mp = rc->conn->mem_pool; 318318Smax.romanov@nginx.com engine = task->thread->engine; 319167Smax.romanov@nginx.com 320167Smax.romanov@nginx.com ra = nxt_mp_retain(mp, sizeof(nxt_req_app_link_t)); 321167Smax.romanov@nginx.com 322167Smax.romanov@nginx.com if (nxt_slow_path(ra == NULL)) { 323167Smax.romanov@nginx.com return NULL; 324167Smax.romanov@nginx.com } 325167Smax.romanov@nginx.com 326318Smax.romanov@nginx.com nxt_debug(task, "ra stream #%uD create", rc->stream); 327167Smax.romanov@nginx.com 328167Smax.romanov@nginx.com nxt_memzero(ra, sizeof(nxt_req_app_link_t)); 329167Smax.romanov@nginx.com 330318Smax.romanov@nginx.com ra->stream = rc->stream; 331318Smax.romanov@nginx.com ra->app_pid = -1; 332167Smax.romanov@nginx.com ra->rc = rc; 333318Smax.romanov@nginx.com rc->ra = ra; 334318Smax.romanov@nginx.com ra->reply_port = engine->port; 335167Smax.romanov@nginx.com 336167Smax.romanov@nginx.com ra->mem_pool = mp; 337167Smax.romanov@nginx.com 338167Smax.romanov@nginx.com ra->work.handler = NULL; 339318Smax.romanov@nginx.com ra->work.task = &engine->task; 340167Smax.romanov@nginx.com ra->work.obj = ra; 341318Smax.romanov@nginx.com ra->work.data = engine; 342167Smax.romanov@nginx.com 343167Smax.romanov@nginx.com return ra; 344167Smax.romanov@nginx.com } 345167Smax.romanov@nginx.com 346167Smax.romanov@nginx.com 347167Smax.romanov@nginx.com static void 348167Smax.romanov@nginx.com nxt_router_ra_release(nxt_task_t *task, void *obj, void *data) 349167Smax.romanov@nginx.com { 350*343Smax.romanov@nginx.com nxt_req_app_link_t *ra; 351*343Smax.romanov@nginx.com nxt_event_engine_t *engine; 352*343Smax.romanov@nginx.com nxt_req_conn_link_t *rc; 353318Smax.romanov@nginx.com 354318Smax.romanov@nginx.com ra = obj; 355318Smax.romanov@nginx.com engine = data; 356318Smax.romanov@nginx.com 357*343Smax.romanov@nginx.com if (task->thread->engine != engine) { 358*343Smax.romanov@nginx.com if (ra->app_port != NULL) { 359*343Smax.romanov@nginx.com ra->app_pid = ra->app_port->pid; 360318Smax.romanov@nginx.com } 361318Smax.romanov@nginx.com 362318Smax.romanov@nginx.com ra->work.handler = nxt_router_ra_release; 363318Smax.romanov@nginx.com ra->work.task = &engine->task; 364318Smax.romanov@nginx.com ra->work.next = NULL; 365318Smax.romanov@nginx.com 366318Smax.romanov@nginx.com nxt_debug(task, "ra stream #%uD post release to %p", 367318Smax.romanov@nginx.com ra->stream, engine); 368318Smax.romanov@nginx.com 369318Smax.romanov@nginx.com nxt_event_engine_post(engine, &ra->work); 370318Smax.romanov@nginx.com 371318Smax.romanov@nginx.com return; 372318Smax.romanov@nginx.com } 373318Smax.romanov@nginx.com 374*343Smax.romanov@nginx.com nxt_debug(task, "ra stream #%uD release", ra->stream); 375*343Smax.romanov@nginx.com 376*343Smax.romanov@nginx.com rc = ra->rc; 377*343Smax.romanov@nginx.com 378*343Smax.romanov@nginx.com if (rc != NULL) { 379*343Smax.romanov@nginx.com if (ra->app_pid != -1) { 380*343Smax.romanov@nginx.com nxt_port_rpc_ex_set_peer(task, engine->port, rc, ra->app_pid); 381*343Smax.romanov@nginx.com } 382*343Smax.romanov@nginx.com 383*343Smax.romanov@nginx.com rc->app_port = ra->app_port; 384*343Smax.romanov@nginx.com 385*343Smax.romanov@nginx.com ra->app_port = NULL; 386*343Smax.romanov@nginx.com rc->ra = NULL; 387*343Smax.romanov@nginx.com ra->rc = NULL; 388318Smax.romanov@nginx.com } 389318Smax.romanov@nginx.com 390*343Smax.romanov@nginx.com if (ra->app_port != NULL) { 391*343Smax.romanov@nginx.com nxt_router_app_port_release(task, ra->app_port, 0, 1); 392*343Smax.romanov@nginx.com 393*343Smax.romanov@nginx.com ra->app_port = NULL; 394*343Smax.romanov@nginx.com } 395318Smax.romanov@nginx.com 396318Smax.romanov@nginx.com nxt_mp_release(ra->mem_pool, ra); 397318Smax.romanov@nginx.com } 398318Smax.romanov@nginx.com 399318Smax.romanov@nginx.com 400318Smax.romanov@nginx.com static void 401318Smax.romanov@nginx.com nxt_router_ra_abort(nxt_task_t *task, void *obj, void *data) 402318Smax.romanov@nginx.com { 403*343Smax.romanov@nginx.com nxt_conn_t *c; 404*343Smax.romanov@nginx.com nxt_req_app_link_t *ra; 405*343Smax.romanov@nginx.com nxt_req_conn_link_t *rc; 406*343Smax.romanov@nginx.com nxt_event_engine_t *engine; 407167Smax.romanov@nginx.com 408167Smax.romanov@nginx.com ra = obj; 409167Smax.romanov@nginx.com engine = data; 410167Smax.romanov@nginx.com 411167Smax.romanov@nginx.com if (task->thread->engine != engine) { 412318Smax.romanov@nginx.com ra->work.handler = nxt_router_ra_abort; 413167Smax.romanov@nginx.com ra->work.task = &engine->task; 414167Smax.romanov@nginx.com ra->work.next = NULL; 415167Smax.romanov@nginx.com 416318Smax.romanov@nginx.com nxt_debug(task, "ra stream #%uD post abort to %p", ra->stream, engine); 417167Smax.romanov@nginx.com 418167Smax.romanov@nginx.com nxt_event_engine_post(engine, &ra->work); 419167Smax.romanov@nginx.com 420167Smax.romanov@nginx.com return; 421167Smax.romanov@nginx.com } 422167Smax.romanov@nginx.com 423318Smax.romanov@nginx.com nxt_debug(task, "ra stream #%uD abort", ra->stream); 424318Smax.romanov@nginx.com 425*343Smax.romanov@nginx.com rc = ra->rc; 426*343Smax.romanov@nginx.com 427*343Smax.romanov@nginx.com if (rc != NULL) { 428*343Smax.romanov@nginx.com c = rc->conn; 429318Smax.romanov@nginx.com 430318Smax.romanov@nginx.com nxt_router_gen_error(task, c, 500, 431318Smax.romanov@nginx.com "Failed to start application worker"); 432*343Smax.romanov@nginx.com 433*343Smax.romanov@nginx.com rc->ra = NULL; 434*343Smax.romanov@nginx.com ra->rc = NULL; 435*343Smax.romanov@nginx.com } 436*343Smax.romanov@nginx.com 437*343Smax.romanov@nginx.com if (ra->app_port != NULL) { 438*343Smax.romanov@nginx.com nxt_router_app_port_release(task, ra->app_port, 0, 1); 439*343Smax.romanov@nginx.com 440*343Smax.romanov@nginx.com ra->app_port = NULL; 441167Smax.romanov@nginx.com } 442167Smax.romanov@nginx.com 443167Smax.romanov@nginx.com nxt_mp_release(ra->mem_pool, ra); 444167Smax.romanov@nginx.com } 445167Smax.romanov@nginx.com 446167Smax.romanov@nginx.com 447*343Smax.romanov@nginx.com nxt_inline void 448*343Smax.romanov@nginx.com nxt_router_rc_unlink(nxt_task_t *task, nxt_req_conn_link_t *rc) 449*343Smax.romanov@nginx.com { 450*343Smax.romanov@nginx.com nxt_req_app_link_t *ra; 451*343Smax.romanov@nginx.com 452*343Smax.romanov@nginx.com if (rc->app_port != NULL) { 453*343Smax.romanov@nginx.com nxt_router_app_port_release(task, rc->app_port, 0, 1); 454*343Smax.romanov@nginx.com 455*343Smax.romanov@nginx.com rc->app_port = NULL; 456*343Smax.romanov@nginx.com } 457*343Smax.romanov@nginx.com 458*343Smax.romanov@nginx.com ra = rc->ra; 459*343Smax.romanov@nginx.com 460*343Smax.romanov@nginx.com if (ra != NULL) { 461*343Smax.romanov@nginx.com rc->ra = NULL; 462*343Smax.romanov@nginx.com ra->rc = NULL; 463*343Smax.romanov@nginx.com 464*343Smax.romanov@nginx.com nxt_thread_mutex_lock(&rc->app->mutex); 465*343Smax.romanov@nginx.com 466*343Smax.romanov@nginx.com if (ra->link.next != NULL) { 467*343Smax.romanov@nginx.com nxt_queue_remove(&ra->link); 468*343Smax.romanov@nginx.com 469*343Smax.romanov@nginx.com ra->link.next = NULL; 470*343Smax.romanov@nginx.com 471*343Smax.romanov@nginx.com } else { 472*343Smax.romanov@nginx.com ra = NULL; 473*343Smax.romanov@nginx.com } 474*343Smax.romanov@nginx.com 475*343Smax.romanov@nginx.com nxt_thread_mutex_unlock(&rc->app->mutex); 476*343Smax.romanov@nginx.com } 477*343Smax.romanov@nginx.com 478*343Smax.romanov@nginx.com if (ra != NULL) { 479*343Smax.romanov@nginx.com nxt_router_ra_release(task, ra, ra->work.data); 480*343Smax.romanov@nginx.com } 481*343Smax.romanov@nginx.com 482*343Smax.romanov@nginx.com if (rc->app != NULL) { 483*343Smax.romanov@nginx.com nxt_router_app_use(task, rc->app, -1); 484*343Smax.romanov@nginx.com 485*343Smax.romanov@nginx.com rc->app = NULL; 486*343Smax.romanov@nginx.com } 487*343Smax.romanov@nginx.com 488*343Smax.romanov@nginx.com nxt_queue_remove(&rc->link); 489*343Smax.romanov@nginx.com 490*343Smax.romanov@nginx.com rc->conn = NULL; 491*343Smax.romanov@nginx.com } 492*343Smax.romanov@nginx.com 493*343Smax.romanov@nginx.com 494141Smax.romanov@nginx.com void 495141Smax.romanov@nginx.com nxt_router_new_port_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg) 496141Smax.romanov@nginx.com { 497141Smax.romanov@nginx.com nxt_port_new_port_handler(task, msg); 498141Smax.romanov@nginx.com 499192Smax.romanov@nginx.com if (msg->port_msg.stream == 0) { 500141Smax.romanov@nginx.com return; 501141Smax.romanov@nginx.com } 502141Smax.romanov@nginx.com 503192Smax.romanov@nginx.com if (msg->new_port == NULL || msg->new_port->type != NXT_PROCESS_WORKER) { 504192Smax.romanov@nginx.com msg->port_msg.type = _NXT_PORT_MSG_RPC_ERROR; 505141Smax.romanov@nginx.com } 506192Smax.romanov@nginx.com 507192Smax.romanov@nginx.com nxt_port_rpc_handler(task, msg); 508141Smax.romanov@nginx.com } 509141Smax.romanov@nginx.com 510141Smax.romanov@nginx.com 511139Sigor@sysoev.ru void 512139Sigor@sysoev.ru nxt_router_conf_data_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg) 513115Sigor@sysoev.ru { 514139Sigor@sysoev.ru size_t dump_size; 515198Sigor@sysoev.ru nxt_int_t ret; 516139Sigor@sysoev.ru nxt_buf_t *b; 517139Sigor@sysoev.ru nxt_router_temp_conf_t *tmcf; 518139Sigor@sysoev.ru 519139Sigor@sysoev.ru b = msg->buf; 520139Sigor@sysoev.ru 521139Sigor@sysoev.ru dump_size = nxt_buf_used_size(b); 522139Sigor@sysoev.ru 523139Sigor@sysoev.ru if (dump_size > 300) { 524139Sigor@sysoev.ru dump_size = 300; 52553Sigor@sysoev.ru } 52653Sigor@sysoev.ru 527139Sigor@sysoev.ru nxt_debug(task, "router conf data (%z): %*s", 528139Sigor@sysoev.ru msg->size, dump_size, b->mem.pos); 529139Sigor@sysoev.ru 530139Sigor@sysoev.ru tmcf = nxt_router_temp_conf(task); 531139Sigor@sysoev.ru if (nxt_slow_path(tmcf == NULL)) { 532139Sigor@sysoev.ru return; 53353Sigor@sysoev.ru } 53453Sigor@sysoev.ru 535139Sigor@sysoev.ru tmcf->conf->router = nxt_router; 536139Sigor@sysoev.ru tmcf->stream = msg->port_msg.stream; 537139Sigor@sysoev.ru tmcf->port = nxt_runtime_port_find(task->thread->runtime, 538198Sigor@sysoev.ru msg->port_msg.pid, 539198Sigor@sysoev.ru msg->port_msg.reply_port); 540198Sigor@sysoev.ru 541198Sigor@sysoev.ru ret = nxt_router_conf_create(task, tmcf, b->mem.pos, b->mem.free); 542198Sigor@sysoev.ru 543198Sigor@sysoev.ru if (nxt_fast_path(ret == NXT_OK)) { 544198Sigor@sysoev.ru nxt_router_conf_apply(task, tmcf, NULL); 545198Sigor@sysoev.ru 546198Sigor@sysoev.ru } else { 547198Sigor@sysoev.ru nxt_router_conf_error(task, tmcf); 548139Sigor@sysoev.ru } 54953Sigor@sysoev.ru } 55053Sigor@sysoev.ru 55153Sigor@sysoev.ru 552192Smax.romanov@nginx.com void 553192Smax.romanov@nginx.com nxt_router_remove_pid_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg) 554192Smax.romanov@nginx.com { 555318Smax.romanov@nginx.com nxt_mp_t *mp; 556318Smax.romanov@nginx.com nxt_buf_t *buf; 557318Smax.romanov@nginx.com nxt_event_engine_t *engine; 558318Smax.romanov@nginx.com nxt_remove_pid_msg_t *rp; 559318Smax.romanov@nginx.com 560192Smax.romanov@nginx.com nxt_port_remove_pid_handler(task, msg); 561192Smax.romanov@nginx.com 562192Smax.romanov@nginx.com if (msg->port_msg.stream == 0) { 563192Smax.romanov@nginx.com return; 564192Smax.romanov@nginx.com } 565192Smax.romanov@nginx.com 566318Smax.romanov@nginx.com mp = nxt_mp_create(1024, 128, 256, 32); 567318Smax.romanov@nginx.com 568318Smax.romanov@nginx.com buf = nxt_buf_mem_alloc(mp, nxt_buf_used_size(msg->buf), 0); 569318Smax.romanov@nginx.com buf->mem.free = nxt_cpymem(buf->mem.free, msg->buf->mem.pos, 570318Smax.romanov@nginx.com nxt_buf_used_size(msg->buf)); 571318Smax.romanov@nginx.com 572318Smax.romanov@nginx.com nxt_queue_each(engine, &nxt_router->engines, nxt_event_engine_t, link0) 573318Smax.romanov@nginx.com { 574318Smax.romanov@nginx.com rp = nxt_mp_retain(mp, sizeof(nxt_remove_pid_msg_t)); 575318Smax.romanov@nginx.com 576318Smax.romanov@nginx.com rp->mem_pool = mp; 577318Smax.romanov@nginx.com 578318Smax.romanov@nginx.com rp->msg.fd = msg->fd; 579318Smax.romanov@nginx.com rp->msg.buf = buf; 580318Smax.romanov@nginx.com rp->msg.port = engine->port; 581318Smax.romanov@nginx.com rp->msg.port_msg = msg->port_msg; 582318Smax.romanov@nginx.com rp->msg.size = msg->size; 583318Smax.romanov@nginx.com rp->msg.new_port = NULL; 584318Smax.romanov@nginx.com 585318Smax.romanov@nginx.com rp->work.handler = nxt_router_worker_remove_pid_handler; 586318Smax.romanov@nginx.com rp->work.task = &engine->task; 587318Smax.romanov@nginx.com rp->work.obj = rp; 588318Smax.romanov@nginx.com rp->work.data = task->thread->engine; 589318Smax.romanov@nginx.com rp->work.next = NULL; 590318Smax.romanov@nginx.com 591318Smax.romanov@nginx.com nxt_event_engine_post(engine, &rp->work); 592318Smax.romanov@nginx.com } 593318Smax.romanov@nginx.com nxt_queue_loop; 594318Smax.romanov@nginx.com 595340Smax.romanov@nginx.com nxt_mp_release(mp, NULL); 596340Smax.romanov@nginx.com 597192Smax.romanov@nginx.com msg->port_msg.type = _NXT_PORT_MSG_RPC_ERROR; 598192Smax.romanov@nginx.com 599192Smax.romanov@nginx.com nxt_port_rpc_handler(task, msg); 600192Smax.romanov@nginx.com } 601192Smax.romanov@nginx.com 602192Smax.romanov@nginx.com 603318Smax.romanov@nginx.com static void 604318Smax.romanov@nginx.com nxt_router_worker_remove_pid_handler(nxt_task_t *task, void *obj, void *data) 605318Smax.romanov@nginx.com { 606*343Smax.romanov@nginx.com nxt_pid_t pid; 607*343Smax.romanov@nginx.com nxt_buf_t *buf; 608318Smax.romanov@nginx.com nxt_event_engine_t *engine; 609318Smax.romanov@nginx.com nxt_remove_pid_msg_t *rp; 610318Smax.romanov@nginx.com 611318Smax.romanov@nginx.com rp = obj; 612318Smax.romanov@nginx.com 613*343Smax.romanov@nginx.com buf = rp->msg.buf; 614*343Smax.romanov@nginx.com 615*343Smax.romanov@nginx.com nxt_assert(nxt_buf_used_size(buf) == sizeof(pid)); 616*343Smax.romanov@nginx.com 617*343Smax.romanov@nginx.com nxt_memcpy(&pid, buf->mem.pos, sizeof(pid)); 618*343Smax.romanov@nginx.com 619*343Smax.romanov@nginx.com nxt_port_rpc_remove_peer(task, rp->msg.port, pid); 620318Smax.romanov@nginx.com 621318Smax.romanov@nginx.com engine = rp->work.data; 622318Smax.romanov@nginx.com 623318Smax.romanov@nginx.com rp->work.handler = nxt_router_worker_remove_pid_done; 624318Smax.romanov@nginx.com rp->work.task = &engine->task; 625318Smax.romanov@nginx.com rp->work.next = NULL; 626318Smax.romanov@nginx.com 627318Smax.romanov@nginx.com nxt_event_engine_post(engine, &rp->work); 628318Smax.romanov@nginx.com } 629318Smax.romanov@nginx.com 630318Smax.romanov@nginx.com 631318Smax.romanov@nginx.com static void 632318Smax.romanov@nginx.com nxt_router_worker_remove_pid_done(nxt_task_t *task, void *obj, void *data) 633318Smax.romanov@nginx.com { 634318Smax.romanov@nginx.com nxt_remove_pid_msg_t *rp; 635318Smax.romanov@nginx.com 636318Smax.romanov@nginx.com rp = obj; 637318Smax.romanov@nginx.com 638318Smax.romanov@nginx.com nxt_mp_release(rp->mem_pool, rp); 639318Smax.romanov@nginx.com } 640318Smax.romanov@nginx.com 641318Smax.romanov@nginx.com 64253Sigor@sysoev.ru static nxt_router_temp_conf_t * 643139Sigor@sysoev.ru nxt_router_temp_conf(nxt_task_t *task) 64453Sigor@sysoev.ru { 64565Sigor@sysoev.ru nxt_mp_t *mp, *tmp; 64653Sigor@sysoev.ru nxt_router_conf_t *rtcf; 64753Sigor@sysoev.ru nxt_router_temp_conf_t *tmcf; 64853Sigor@sysoev.ru 64965Sigor@sysoev.ru mp = nxt_mp_create(1024, 128, 256, 32); 65053Sigor@sysoev.ru if (nxt_slow_path(mp == NULL)) { 65153Sigor@sysoev.ru return NULL; 65253Sigor@sysoev.ru } 65353Sigor@sysoev.ru 65465Sigor@sysoev.ru rtcf = nxt_mp_zget(mp, sizeof(nxt_router_conf_t)); 65553Sigor@sysoev.ru if (nxt_slow_path(rtcf == NULL)) { 65653Sigor@sysoev.ru goto fail; 65753Sigor@sysoev.ru } 65853Sigor@sysoev.ru 65953Sigor@sysoev.ru rtcf->mem_pool = mp; 66053Sigor@sysoev.ru 66165Sigor@sysoev.ru tmp = nxt_mp_create(1024, 128, 256, 32); 66253Sigor@sysoev.ru if (nxt_slow_path(tmp == NULL)) { 66353Sigor@sysoev.ru goto fail; 66453Sigor@sysoev.ru } 66553Sigor@sysoev.ru 66665Sigor@sysoev.ru tmcf = nxt_mp_zget(tmp, sizeof(nxt_router_temp_conf_t)); 66753Sigor@sysoev.ru if (nxt_slow_path(tmcf == NULL)) { 66853Sigor@sysoev.ru goto temp_fail; 66953Sigor@sysoev.ru } 67053Sigor@sysoev.ru 67153Sigor@sysoev.ru tmcf->mem_pool = tmp; 67253Sigor@sysoev.ru tmcf->conf = rtcf; 673139Sigor@sysoev.ru tmcf->count = 1; 674139Sigor@sysoev.ru tmcf->engine = task->thread->engine; 67553Sigor@sysoev.ru 67653Sigor@sysoev.ru tmcf->engines = nxt_array_create(tmcf->mem_pool, 4, 67753Sigor@sysoev.ru sizeof(nxt_router_engine_conf_t)); 67853Sigor@sysoev.ru if (nxt_slow_path(tmcf->engines == NULL)) { 67953Sigor@sysoev.ru goto temp_fail; 68053Sigor@sysoev.ru } 68153Sigor@sysoev.ru 68253Sigor@sysoev.ru nxt_queue_init(&tmcf->deleting); 68353Sigor@sysoev.ru nxt_queue_init(&tmcf->keeping); 68453Sigor@sysoev.ru nxt_queue_init(&tmcf->updating); 68553Sigor@sysoev.ru nxt_queue_init(&tmcf->pending); 68653Sigor@sysoev.ru nxt_queue_init(&tmcf->creating); 687133Sigor@sysoev.ru nxt_queue_init(&tmcf->apps); 688133Sigor@sysoev.ru nxt_queue_init(&tmcf->previous); 68953Sigor@sysoev.ru 69053Sigor@sysoev.ru return tmcf; 69153Sigor@sysoev.ru 69253Sigor@sysoev.ru temp_fail: 69353Sigor@sysoev.ru 69465Sigor@sysoev.ru nxt_mp_destroy(tmp); 69553Sigor@sysoev.ru 69653Sigor@sysoev.ru fail: 69753Sigor@sysoev.ru 69865Sigor@sysoev.ru nxt_mp_destroy(mp); 69953Sigor@sysoev.ru 70053Sigor@sysoev.ru return NULL; 70153Sigor@sysoev.ru } 70253Sigor@sysoev.ru 70353Sigor@sysoev.ru 704198Sigor@sysoev.ru static void 705198Sigor@sysoev.ru nxt_router_conf_apply(nxt_task_t *task, void *obj, void *data) 706139Sigor@sysoev.ru { 707139Sigor@sysoev.ru nxt_int_t ret; 708139Sigor@sysoev.ru nxt_router_t *router; 709139Sigor@sysoev.ru nxt_runtime_t *rt; 710198Sigor@sysoev.ru nxt_queue_link_t *qlk; 711198Sigor@sysoev.ru nxt_socket_conf_t *skcf; 712198Sigor@sysoev.ru nxt_router_temp_conf_t *tmcf; 713139Sigor@sysoev.ru const nxt_event_interface_t *interface; 714139Sigor@sysoev.ru 715198Sigor@sysoev.ru tmcf = obj; 716198Sigor@sysoev.ru 717198Sigor@sysoev.ru qlk = nxt_queue_first(&tmcf->pending); 718198Sigor@sysoev.ru 719198Sigor@sysoev.ru if (qlk != nxt_queue_tail(&tmcf->pending)) { 720198Sigor@sysoev.ru nxt_queue_remove(qlk); 721198Sigor@sysoev.ru nxt_queue_insert_tail(&tmcf->creating, qlk); 722198Sigor@sysoev.ru 723198Sigor@sysoev.ru skcf = nxt_queue_link_data(qlk, nxt_socket_conf_t, link); 724198Sigor@sysoev.ru 725198Sigor@sysoev.ru nxt_router_listen_socket_rpc_create(task, tmcf, skcf); 726198Sigor@sysoev.ru 727198Sigor@sysoev.ru return; 728139Sigor@sysoev.ru } 729139Sigor@sysoev.ru 730139Sigor@sysoev.ru rt = task->thread->runtime; 731139Sigor@sysoev.ru 732139Sigor@sysoev.ru interface = nxt_service_get(rt->services, "engine", NULL); 733139Sigor@sysoev.ru 734198Sigor@sysoev.ru router = tmcf->conf->router; 735198Sigor@sysoev.ru 736139Sigor@sysoev.ru ret = nxt_router_engines_create(task, router, tmcf, interface); 737139Sigor@sysoev.ru if (nxt_slow_path(ret != NXT_OK)) { 738198Sigor@sysoev.ru goto fail; 739139Sigor@sysoev.ru } 740139Sigor@sysoev.ru 741139Sigor@sysoev.ru ret = nxt_router_threads_create(task, rt, tmcf); 742139Sigor@sysoev.ru if (nxt_slow_path(ret != NXT_OK)) { 743198Sigor@sysoev.ru goto fail; 744139Sigor@sysoev.ru } 745139Sigor@sysoev.ru 746*343Smax.romanov@nginx.com nxt_router_apps_sort(task, router, tmcf); 747139Sigor@sysoev.ru 748315Sigor@sysoev.ru nxt_router_engines_post(router, tmcf); 749139Sigor@sysoev.ru 750139Sigor@sysoev.ru nxt_queue_add(&router->sockets, &tmcf->updating); 751139Sigor@sysoev.ru nxt_queue_add(&router->sockets, &tmcf->creating); 752139Sigor@sysoev.ru 753198Sigor@sysoev.ru nxt_router_conf_ready(task, tmcf); 754198Sigor@sysoev.ru 755198Sigor@sysoev.ru return; 756198Sigor@sysoev.ru 757198Sigor@sysoev.ru fail: 758198Sigor@sysoev.ru 759198Sigor@sysoev.ru nxt_router_conf_error(task, tmcf); 760198Sigor@sysoev.ru 761198Sigor@sysoev.ru return; 762139Sigor@sysoev.ru } 763139Sigor@sysoev.ru 764139Sigor@sysoev.ru 765139Sigor@sysoev.ru static void 766139Sigor@sysoev.ru nxt_router_conf_wait(nxt_task_t *task, void *obj, void *data) 767139Sigor@sysoev.ru { 768153Sigor@sysoev.ru nxt_joint_job_t *job; 769153Sigor@sysoev.ru 770153Sigor@sysoev.ru job = obj; 771153Sigor@sysoev.ru 772198Sigor@sysoev.ru nxt_router_conf_ready(task, job->tmcf); 773139Sigor@sysoev.ru } 774139Sigor@sysoev.ru 775139Sigor@sysoev.ru 776139Sigor@sysoev.ru static void 777198Sigor@sysoev.ru nxt_router_conf_ready(nxt_task_t *task, nxt_router_temp_conf_t *tmcf) 778139Sigor@sysoev.ru { 779139Sigor@sysoev.ru nxt_debug(task, "temp conf count:%D", tmcf->count); 780139Sigor@sysoev.ru 781139Sigor@sysoev.ru if (--tmcf->count == 0) { 782193Smax.romanov@nginx.com nxt_router_conf_send(task, tmcf, NXT_PORT_MSG_RPC_READY_LAST); 783139Sigor@sysoev.ru } 784139Sigor@sysoev.ru } 785139Sigor@sysoev.ru 786139Sigor@sysoev.ru 787139Sigor@sysoev.ru static void 788139Sigor@sysoev.ru nxt_router_conf_error(nxt_task_t *task, nxt_router_temp_conf_t *tmcf) 789139Sigor@sysoev.ru { 790148Sigor@sysoev.ru nxt_socket_t s; 791149Sigor@sysoev.ru nxt_router_t *router; 792148Sigor@sysoev.ru nxt_queue_link_t *qlk; 793148Sigor@sysoev.ru nxt_socket_conf_t *skcf; 794148Sigor@sysoev.ru 795198Sigor@sysoev.ru nxt_log(task, NXT_LOG_CRIT, "failed to apply new conf"); 796198Sigor@sysoev.ru 797148Sigor@sysoev.ru for (qlk = nxt_queue_first(&tmcf->creating); 798148Sigor@sysoev.ru qlk != nxt_queue_tail(&tmcf->creating); 799148Sigor@sysoev.ru qlk = nxt_queue_next(qlk)) 800148Sigor@sysoev.ru { 801148Sigor@sysoev.ru skcf = nxt_queue_link_data(qlk, nxt_socket_conf_t, link); 802148Sigor@sysoev.ru s = skcf->listen.socket; 803148Sigor@sysoev.ru 804148Sigor@sysoev.ru if (s != -1) { 805148Sigor@sysoev.ru nxt_socket_close(task, s); 806148Sigor@sysoev.ru } 807148Sigor@sysoev.ru 808148Sigor@sysoev.ru nxt_free(skcf->socket); 809148Sigor@sysoev.ru } 810148Sigor@sysoev.ru 811149Sigor@sysoev.ru router = tmcf->conf->router; 812149Sigor@sysoev.ru 813149Sigor@sysoev.ru nxt_queue_add(&router->sockets, &tmcf->keeping); 814149Sigor@sysoev.ru nxt_queue_add(&router->sockets, &tmcf->deleting); 815149Sigor@sysoev.ru 816148Sigor@sysoev.ru // TODO: new engines and threads 817148Sigor@sysoev.ru 818139Sigor@sysoev.ru nxt_mp_destroy(tmcf->conf->mem_pool); 819139Sigor@sysoev.ru 820193Smax.romanov@nginx.com nxt_router_conf_send(task, tmcf, NXT_PORT_MSG_RPC_ERROR); 821139Sigor@sysoev.ru } 822139Sigor@sysoev.ru 823139Sigor@sysoev.ru 824139Sigor@sysoev.ru static void 825139Sigor@sysoev.ru nxt_router_conf_send(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, 826193Smax.romanov@nginx.com nxt_port_msg_type_t type) 827139Sigor@sysoev.ru { 828193Smax.romanov@nginx.com nxt_port_socket_write(task, tmcf->port, type, -1, tmcf->stream, 0, NULL); 829139Sigor@sysoev.ru } 830139Sigor@sysoev.ru 831139Sigor@sysoev.ru 832115Sigor@sysoev.ru static nxt_conf_map_t nxt_router_conf[] = { 833115Sigor@sysoev.ru { 834133Sigor@sysoev.ru nxt_string("listeners_threads"), 835115Sigor@sysoev.ru NXT_CONF_MAP_INT32, 836115Sigor@sysoev.ru offsetof(nxt_router_conf_t, threads), 837115Sigor@sysoev.ru }, 838115Sigor@sysoev.ru }; 839115Sigor@sysoev.ru 840115Sigor@sysoev.ru 841133Sigor@sysoev.ru static nxt_conf_map_t nxt_router_app_conf[] = { 842115Sigor@sysoev.ru { 843133Sigor@sysoev.ru nxt_string("type"), 844115Sigor@sysoev.ru NXT_CONF_MAP_STR, 845133Sigor@sysoev.ru offsetof(nxt_router_app_conf_t, type), 846115Sigor@sysoev.ru }, 847115Sigor@sysoev.ru 848115Sigor@sysoev.ru { 849133Sigor@sysoev.ru nxt_string("workers"), 850115Sigor@sysoev.ru NXT_CONF_MAP_INT32, 851133Sigor@sysoev.ru offsetof(nxt_router_app_conf_t, workers), 852133Sigor@sysoev.ru }, 853318Smax.romanov@nginx.com 854318Smax.romanov@nginx.com { 855318Smax.romanov@nginx.com nxt_string("limits"), 856318Smax.romanov@nginx.com NXT_CONF_MAP_PTR, 857318Smax.romanov@nginx.com offsetof(nxt_router_app_conf_t, limits_value), 858318Smax.romanov@nginx.com }, 859318Smax.romanov@nginx.com }; 860318Smax.romanov@nginx.com 861318Smax.romanov@nginx.com 862318Smax.romanov@nginx.com static nxt_conf_map_t nxt_router_app_limits_conf[] = { 863318Smax.romanov@nginx.com { 864318Smax.romanov@nginx.com nxt_string("timeout"), 865318Smax.romanov@nginx.com NXT_CONF_MAP_MSEC, 866318Smax.romanov@nginx.com offsetof(nxt_router_app_conf_t, timeout), 867318Smax.romanov@nginx.com }, 868318Smax.romanov@nginx.com 869318Smax.romanov@nginx.com { 870318Smax.romanov@nginx.com nxt_string("requests"), 871318Smax.romanov@nginx.com NXT_CONF_MAP_INT32, 872318Smax.romanov@nginx.com offsetof(nxt_router_app_conf_t, requests), 873318Smax.romanov@nginx.com }, 874133Sigor@sysoev.ru }; 875