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; 32343Smax.romanov@nginx.com nxt_app_t *app; 33318Smax.romanov@nginx.com nxt_port_t *app_port; 34346Smax.romanov@nginx.com nxt_app_parse_ctx_t *ap; 35318Smax.romanov@nginx.com nxt_req_app_link_t *ra; 36318Smax.romanov@nginx.com 37318Smax.romanov@nginx.com nxt_queue_link_t link; /* for nxt_conn_t.requests */ 38318Smax.romanov@nginx.com } nxt_req_conn_link_t; 39318Smax.romanov@nginx.com 40318Smax.romanov@nginx.com 41167Smax.romanov@nginx.com struct nxt_req_app_link_s { 42318Smax.romanov@nginx.com uint32_t stream; 43167Smax.romanov@nginx.com nxt_port_t *app_port; 44318Smax.romanov@nginx.com nxt_pid_t app_pid; 45167Smax.romanov@nginx.com nxt_port_t *reply_port; 46167Smax.romanov@nginx.com nxt_app_parse_ctx_t *ap; 47167Smax.romanov@nginx.com nxt_req_conn_link_t *rc; 48167Smax.romanov@nginx.com 49167Smax.romanov@nginx.com nxt_queue_link_t link; /* for nxt_app_t.requests */ 50167Smax.romanov@nginx.com 51167Smax.romanov@nginx.com nxt_mp_t *mem_pool; 52167Smax.romanov@nginx.com nxt_work_t work; 53345Smax.romanov@nginx.com 54345Smax.romanov@nginx.com int err_code; 55345Smax.romanov@nginx.com const char *err_str; 56167Smax.romanov@nginx.com }; 57167Smax.romanov@nginx.com 58167Smax.romanov@nginx.com 59198Sigor@sysoev.ru typedef struct { 60198Sigor@sysoev.ru nxt_socket_conf_t *socket_conf; 61198Sigor@sysoev.ru nxt_router_temp_conf_t *temp_conf; 62198Sigor@sysoev.ru } nxt_socket_rpc_t; 63198Sigor@sysoev.ru 64198Sigor@sysoev.ru 65343Smax.romanov@nginx.com static nxt_int_t nxt_router_start_worker(nxt_task_t *task, nxt_app_t *app); 66343Smax.romanov@nginx.com 67345Smax.romanov@nginx.com static void nxt_router_ra_error(nxt_task_t *task, nxt_req_app_link_t *ra, 68345Smax.romanov@nginx.com int code, const char* str); 69345Smax.romanov@nginx.com 70139Sigor@sysoev.ru static nxt_router_temp_conf_t *nxt_router_temp_conf(nxt_task_t *task); 71198Sigor@sysoev.ru static void nxt_router_conf_apply(nxt_task_t *task, void *obj, void *data); 72198Sigor@sysoev.ru static void nxt_router_conf_ready(nxt_task_t *task, 73139Sigor@sysoev.ru nxt_router_temp_conf_t *tmcf); 74139Sigor@sysoev.ru static void nxt_router_conf_error(nxt_task_t *task, 75139Sigor@sysoev.ru nxt_router_temp_conf_t *tmcf); 76139Sigor@sysoev.ru static void nxt_router_conf_send(nxt_task_t *task, 77193Smax.romanov@nginx.com nxt_router_temp_conf_t *tmcf, nxt_port_msg_type_t type); 7853Sigor@sysoev.ru static void nxt_router_listen_sockets_sort(nxt_router_t *router, 7953Sigor@sysoev.ru nxt_router_temp_conf_t *tmcf); 8053Sigor@sysoev.ru 81115Sigor@sysoev.ru static nxt_int_t nxt_router_conf_create(nxt_task_t *task, 82115Sigor@sysoev.ru nxt_router_temp_conf_t *tmcf, u_char *start, u_char *end); 83133Sigor@sysoev.ru static nxt_app_t *nxt_router_app_find(nxt_queue_t *queue, nxt_str_t *name); 84133Sigor@sysoev.ru static nxt_app_t *nxt_router_listener_application(nxt_router_temp_conf_t *tmcf, 85133Sigor@sysoev.ru nxt_str_t *name); 86198Sigor@sysoev.ru static void nxt_router_listen_socket_rpc_create(nxt_task_t *task, 87198Sigor@sysoev.ru nxt_router_temp_conf_t *tmcf, nxt_socket_conf_t *skcf); 88198Sigor@sysoev.ru static void nxt_router_listen_socket_ready(nxt_task_t *task, 89198Sigor@sysoev.ru nxt_port_recv_msg_t *msg, void *data); 90198Sigor@sysoev.ru static void nxt_router_listen_socket_error(nxt_task_t *task, 91198Sigor@sysoev.ru nxt_port_recv_msg_t *msg, void *data); 9265Sigor@sysoev.ru static nxt_socket_conf_t *nxt_router_socket_conf(nxt_task_t *task, nxt_mp_t *mp, 9365Sigor@sysoev.ru nxt_sockaddr_t *sa); 9453Sigor@sysoev.ru 9553Sigor@sysoev.ru static nxt_int_t nxt_router_engines_create(nxt_task_t *task, 9653Sigor@sysoev.ru nxt_router_t *router, nxt_router_temp_conf_t *tmcf, 9753Sigor@sysoev.ru const nxt_event_interface_t *interface); 98115Sigor@sysoev.ru static nxt_int_t nxt_router_engine_conf_create(nxt_router_temp_conf_t *tmcf, 99115Sigor@sysoev.ru nxt_router_engine_conf_t *recf); 100115Sigor@sysoev.ru static nxt_int_t nxt_router_engine_conf_update(nxt_router_temp_conf_t *tmcf, 101115Sigor@sysoev.ru nxt_router_engine_conf_t *recf); 102115Sigor@sysoev.ru static nxt_int_t nxt_router_engine_conf_delete(nxt_router_temp_conf_t *tmcf, 103115Sigor@sysoev.ru nxt_router_engine_conf_t *recf); 104115Sigor@sysoev.ru static void nxt_router_engine_socket_count(nxt_queue_t *sockets); 105154Sigor@sysoev.ru static nxt_int_t nxt_router_engine_joints_create(nxt_router_temp_conf_t *tmcf, 106154Sigor@sysoev.ru nxt_router_engine_conf_t *recf, nxt_queue_t *sockets, 107154Sigor@sysoev.ru nxt_work_handler_t handler); 108313Sigor@sysoev.ru static nxt_int_t nxt_router_engine_quit(nxt_router_temp_conf_t *tmcf, 109313Sigor@sysoev.ru nxt_router_engine_conf_t *recf); 110139Sigor@sysoev.ru static nxt_int_t nxt_router_engine_joints_delete(nxt_router_temp_conf_t *tmcf, 111139Sigor@sysoev.ru nxt_router_engine_conf_t *recf, nxt_queue_t *sockets); 11253Sigor@sysoev.ru 11353Sigor@sysoev.ru static nxt_int_t nxt_router_threads_create(nxt_task_t *task, nxt_runtime_t *rt, 11453Sigor@sysoev.ru nxt_router_temp_conf_t *tmcf); 11553Sigor@sysoev.ru static nxt_int_t nxt_router_thread_create(nxt_task_t *task, nxt_runtime_t *rt, 11653Sigor@sysoev.ru nxt_event_engine_t *engine); 117343Smax.romanov@nginx.com static void nxt_router_apps_sort(nxt_task_t *task, nxt_router_t *router, 118133Sigor@sysoev.ru nxt_router_temp_conf_t *tmcf); 11953Sigor@sysoev.ru 120315Sigor@sysoev.ru static void nxt_router_engines_post(nxt_router_t *router, 121315Sigor@sysoev.ru nxt_router_temp_conf_t *tmcf); 122315Sigor@sysoev.ru static void nxt_router_engine_post(nxt_event_engine_t *engine, 123315Sigor@sysoev.ru nxt_work_t *jobs); 12453Sigor@sysoev.ru 12553Sigor@sysoev.ru static void nxt_router_thread_start(void *data); 12653Sigor@sysoev.ru static void nxt_router_listen_socket_create(nxt_task_t *task, void *obj, 12753Sigor@sysoev.ru void *data); 12853Sigor@sysoev.ru static void nxt_router_listen_socket_update(nxt_task_t *task, void *obj, 12953Sigor@sysoev.ru void *data); 13053Sigor@sysoev.ru static void nxt_router_listen_socket_delete(nxt_task_t *task, void *obj, 13153Sigor@sysoev.ru void *data); 132313Sigor@sysoev.ru static void nxt_router_worker_thread_quit(nxt_task_t *task, void *obj, 133313Sigor@sysoev.ru void *data); 13453Sigor@sysoev.ru static void nxt_router_listen_socket_close(nxt_task_t *task, void *obj, 13553Sigor@sysoev.ru void *data); 13653Sigor@sysoev.ru static void nxt_router_listen_socket_release(nxt_task_t *task, 13753Sigor@sysoev.ru nxt_socket_conf_joint_t *joint); 13853Sigor@sysoev.ru static void nxt_router_thread_exit_handler(nxt_task_t *task, void *obj, 13953Sigor@sysoev.ru void *data); 14053Sigor@sysoev.ru static void nxt_router_conf_release(nxt_task_t *task, 14153Sigor@sysoev.ru nxt_socket_conf_joint_t *joint); 14253Sigor@sysoev.ru 143343Smax.romanov@nginx.com static void nxt_router_app_port_ready(nxt_task_t *task, 144343Smax.romanov@nginx.com nxt_port_recv_msg_t *msg, void *data); 145343Smax.romanov@nginx.com static void nxt_router_app_port_error(nxt_task_t *task, 146343Smax.romanov@nginx.com nxt_port_recv_msg_t *msg, void *data); 147343Smax.romanov@nginx.com 148343Smax.romanov@nginx.com static nxt_port_t * nxt_router_app_get_idle_port(nxt_app_t *app); 149343Smax.romanov@nginx.com static void nxt_router_app_port_release(nxt_task_t *task, nxt_port_t *port, 150343Smax.romanov@nginx.com uint32_t request_failed, uint32_t got_response); 151141Smax.romanov@nginx.com 15253Sigor@sysoev.ru static void nxt_router_conn_init(nxt_task_t *task, void *obj, void *data); 15353Sigor@sysoev.ru static void nxt_router_conn_http_header_parse(nxt_task_t *task, void *obj, 15453Sigor@sysoev.ru void *data); 155206Smax.romanov@nginx.com static void nxt_router_conn_http_body_read(nxt_task_t *task, void *obj, 156206Smax.romanov@nginx.com void *data); 15788Smax.romanov@nginx.com static void nxt_router_process_http_request(nxt_task_t *task, 15888Smax.romanov@nginx.com nxt_conn_t *c, nxt_app_parse_ctx_t *ap); 159141Smax.romanov@nginx.com static void nxt_router_process_http_request_mp(nxt_task_t *task, 160343Smax.romanov@nginx.com nxt_req_app_link_t *ra); 161216Sigor@sysoev.ru static nxt_int_t nxt_python_prepare_msg(nxt_task_t *task, nxt_app_request_t *r, 162216Sigor@sysoev.ru nxt_app_wmsg_t *wmsg); 163216Sigor@sysoev.ru static nxt_int_t nxt_php_prepare_msg(nxt_task_t *task, nxt_app_request_t *r, 164216Sigor@sysoev.ru nxt_app_wmsg_t *wmsg); 165216Sigor@sysoev.ru static nxt_int_t nxt_go_prepare_msg(nxt_task_t *task, nxt_app_request_t *r, 166216Sigor@sysoev.ru nxt_app_wmsg_t *wmsg); 16788Smax.romanov@nginx.com static void nxt_router_conn_ready(nxt_task_t *task, void *obj, void *data); 16853Sigor@sysoev.ru static void nxt_router_conn_close(nxt_task_t *task, void *obj, void *data); 16953Sigor@sysoev.ru static void nxt_router_conn_free(nxt_task_t *task, void *obj, void *data); 17053Sigor@sysoev.ru static void nxt_router_conn_error(nxt_task_t *task, void *obj, void *data); 17153Sigor@sysoev.ru static void nxt_router_conn_timeout(nxt_task_t *task, void *obj, void *data); 172318Smax.romanov@nginx.com static void nxt_router_app_timeout(nxt_task_t *task, void *obj, void *data); 17362Sigor@sysoev.ru static nxt_msec_t nxt_router_conn_timeout_value(nxt_conn_t *c, uintptr_t data); 17420Sigor@sysoev.ru 175141Smax.romanov@nginx.com static void nxt_router_gen_error(nxt_task_t *task, nxt_conn_t *c, int code, 176345Smax.romanov@nginx.com const char* str); 177141Smax.romanov@nginx.com 178119Smax.romanov@nginx.com static nxt_router_t *nxt_router; 17920Sigor@sysoev.ru 180216Sigor@sysoev.ru 181216Sigor@sysoev.ru static nxt_app_prepare_msg_t nxt_app_prepare_msg[] = { 182216Sigor@sysoev.ru nxt_python_prepare_msg, 183216Sigor@sysoev.ru nxt_php_prepare_msg, 184216Sigor@sysoev.ru nxt_go_prepare_msg, 185216Sigor@sysoev.ru }; 186216Sigor@sysoev.ru 187216Sigor@sysoev.ru 18820Sigor@sysoev.ru nxt_int_t 189141Smax.romanov@nginx.com nxt_router_start(nxt_task_t *task, void *data) 19020Sigor@sysoev.ru { 191141Smax.romanov@nginx.com nxt_int_t ret; 192141Smax.romanov@nginx.com nxt_router_t *router; 193141Smax.romanov@nginx.com nxt_runtime_t *rt; 194141Smax.romanov@nginx.com 195141Smax.romanov@nginx.com rt = task->thread->runtime; 19653Sigor@sysoev.ru 19788Smax.romanov@nginx.com ret = nxt_app_http_init(task, rt); 19888Smax.romanov@nginx.com if (nxt_slow_path(ret != NXT_OK)) { 19988Smax.romanov@nginx.com return ret; 20088Smax.romanov@nginx.com } 20188Smax.romanov@nginx.com 20253Sigor@sysoev.ru router = nxt_zalloc(sizeof(nxt_router_t)); 20353Sigor@sysoev.ru if (nxt_slow_path(router == NULL)) { 20453Sigor@sysoev.ru return NXT_ERROR; 20553Sigor@sysoev.ru } 20653Sigor@sysoev.ru 20753Sigor@sysoev.ru nxt_queue_init(&router->engines); 20853Sigor@sysoev.ru nxt_queue_init(&router->sockets); 209133Sigor@sysoev.ru nxt_queue_init(&router->apps); 21053Sigor@sysoev.ru 211119Smax.romanov@nginx.com nxt_router = router; 212119Smax.romanov@nginx.com 213115Sigor@sysoev.ru return NXT_OK; 214115Sigor@sysoev.ru } 215115Sigor@sysoev.ru 216115Sigor@sysoev.ru 217343Smax.romanov@nginx.com static void 218343Smax.romanov@nginx.com nxt_router_start_worker_handler(nxt_task_t *task, nxt_port_t *port, void *data) 219167Smax.romanov@nginx.com { 220343Smax.romanov@nginx.com size_t size; 221343Smax.romanov@nginx.com uint32_t stream; 222343Smax.romanov@nginx.com nxt_app_t *app; 223343Smax.romanov@nginx.com nxt_buf_t *b; 224343Smax.romanov@nginx.com nxt_port_t *main_port; 225343Smax.romanov@nginx.com nxt_runtime_t *rt; 226343Smax.romanov@nginx.com 227343Smax.romanov@nginx.com app = data; 228167Smax.romanov@nginx.com 229167Smax.romanov@nginx.com rt = task->thread->runtime; 230240Sigor@sysoev.ru main_port = rt->port_by_type[NXT_PROCESS_MAIN]; 231167Smax.romanov@nginx.com 232343Smax.romanov@nginx.com nxt_debug(task, "app '%V' %p start worker", &app->name, app); 233343Smax.romanov@nginx.com 234343Smax.romanov@nginx.com size = app->name.length + 1 + app->conf.length; 235343Smax.romanov@nginx.com 236343Smax.romanov@nginx.com b = nxt_buf_mem_ts_alloc(task, task->thread->engine->mem_pool, size); 237343Smax.romanov@nginx.com 238343Smax.romanov@nginx.com if (nxt_slow_path(b == NULL)) { 239343Smax.romanov@nginx.com goto failed; 240167Smax.romanov@nginx.com } 241167Smax.romanov@nginx.com 242343Smax.romanov@nginx.com nxt_buf_cpystr(b, &app->name); 243343Smax.romanov@nginx.com *b->mem.free++ = '\0'; 244343Smax.romanov@nginx.com nxt_buf_cpystr(b, &app->conf); 245343Smax.romanov@nginx.com 246343Smax.romanov@nginx.com stream = nxt_port_rpc_register_handler(task, port, 247343Smax.romanov@nginx.com nxt_router_app_port_ready, 248343Smax.romanov@nginx.com nxt_router_app_port_error, 249343Smax.romanov@nginx.com -1, app); 250343Smax.romanov@nginx.com 251343Smax.romanov@nginx.com if (nxt_slow_path(stream == 0)) { 252343Smax.romanov@nginx.com nxt_mp_release(b->data, b); 253343Smax.romanov@nginx.com 254343Smax.romanov@nginx.com goto failed; 255343Smax.romanov@nginx.com } 256343Smax.romanov@nginx.com 257343Smax.romanov@nginx.com nxt_port_socket_write(task, main_port, NXT_PORT_MSG_START_WORKER, -1, 258343Smax.romanov@nginx.com stream, port->id, b); 259343Smax.romanov@nginx.com 260343Smax.romanov@nginx.com return; 261343Smax.romanov@nginx.com 262343Smax.romanov@nginx.com failed: 263343Smax.romanov@nginx.com 264343Smax.romanov@nginx.com nxt_thread_mutex_lock(&app->mutex); 265343Smax.romanov@nginx.com 266343Smax.romanov@nginx.com app->pending_workers--; 267343Smax.romanov@nginx.com 268343Smax.romanov@nginx.com nxt_thread_mutex_unlock(&app->mutex); 269343Smax.romanov@nginx.com 270343Smax.romanov@nginx.com nxt_router_app_use(task, app, -1); 271167Smax.romanov@nginx.com } 272167Smax.romanov@nginx.com 273167Smax.romanov@nginx.com 274343Smax.romanov@nginx.com static nxt_int_t 275343Smax.romanov@nginx.com nxt_router_start_worker(nxt_task_t *task, nxt_app_t *app) 276141Smax.romanov@nginx.com { 277343Smax.romanov@nginx.com nxt_int_t res; 278343Smax.romanov@nginx.com nxt_port_t *router_port; 279343Smax.romanov@nginx.com nxt_runtime_t *rt; 280343Smax.romanov@nginx.com 281343Smax.romanov@nginx.com rt = task->thread->runtime; 282343Smax.romanov@nginx.com router_port = rt->port_by_type[NXT_PROCESS_ROUTER]; 283343Smax.romanov@nginx.com 284343Smax.romanov@nginx.com nxt_router_app_use(task, app, 1); 285343Smax.romanov@nginx.com 286343Smax.romanov@nginx.com res = nxt_port_post(task, router_port, nxt_router_start_worker_handler, 287343Smax.romanov@nginx.com app); 288343Smax.romanov@nginx.com 289343Smax.romanov@nginx.com if (res == NXT_OK) { 290343Smax.romanov@nginx.com return res; 291318Smax.romanov@nginx.com } 292318Smax.romanov@nginx.com 293343Smax.romanov@nginx.com nxt_thread_mutex_lock(&app->mutex); 294343Smax.romanov@nginx.com 295343Smax.romanov@nginx.com app->pending_workers--; 296343Smax.romanov@nginx.com 297343Smax.romanov@nginx.com nxt_thread_mutex_unlock(&app->mutex); 298343Smax.romanov@nginx.com 299343Smax.romanov@nginx.com nxt_router_app_use(task, app, -1); 300343Smax.romanov@nginx.com 301343Smax.romanov@nginx.com return NXT_ERROR; 302318Smax.romanov@nginx.com } 303318Smax.romanov@nginx.com 304318Smax.romanov@nginx.com 305*351Smax.romanov@nginx.com nxt_inline void 306*351Smax.romanov@nginx.com nxt_router_ra_init(nxt_task_t *task, nxt_req_app_link_t *ra, 307*351Smax.romanov@nginx.com nxt_req_conn_link_t *rc) 308167Smax.romanov@nginx.com { 309318Smax.romanov@nginx.com nxt_event_engine_t *engine; 310*351Smax.romanov@nginx.com 311318Smax.romanov@nginx.com engine = task->thread->engine; 312167Smax.romanov@nginx.com 313167Smax.romanov@nginx.com nxt_memzero(ra, sizeof(nxt_req_app_link_t)); 314167Smax.romanov@nginx.com 315318Smax.romanov@nginx.com ra->stream = rc->stream; 316318Smax.romanov@nginx.com ra->app_pid = -1; 317167Smax.romanov@nginx.com ra->rc = rc; 318318Smax.romanov@nginx.com rc->ra = ra; 319318Smax.romanov@nginx.com ra->reply_port = engine->port; 320*351Smax.romanov@nginx.com ra->ap = rc->ap; 321167Smax.romanov@nginx.com 322167Smax.romanov@nginx.com ra->work.handler = NULL; 323318Smax.romanov@nginx.com ra->work.task = &engine->task; 324167Smax.romanov@nginx.com ra->work.obj = ra; 325318Smax.romanov@nginx.com ra->work.data = engine; 326*351Smax.romanov@nginx.com } 327*351Smax.romanov@nginx.com 328*351Smax.romanov@nginx.com 329*351Smax.romanov@nginx.com nxt_inline nxt_req_app_link_t * 330*351Smax.romanov@nginx.com nxt_router_ra_create(nxt_task_t *task, nxt_req_app_link_t *ra_src) 331*351Smax.romanov@nginx.com { 332*351Smax.romanov@nginx.com nxt_mp_t *mp; 333*351Smax.romanov@nginx.com nxt_req_app_link_t *ra; 334*351Smax.romanov@nginx.com 335*351Smax.romanov@nginx.com mp = ra_src->ap->mem_pool; 336*351Smax.romanov@nginx.com 337*351Smax.romanov@nginx.com ra = nxt_mp_retain(mp, sizeof(nxt_req_app_link_t)); 338*351Smax.romanov@nginx.com 339*351Smax.romanov@nginx.com if (nxt_slow_path(ra == NULL)) { 340*351Smax.romanov@nginx.com 341*351Smax.romanov@nginx.com ra_src->rc->ra = NULL; 342*351Smax.romanov@nginx.com ra_src->rc = NULL; 343*351Smax.romanov@nginx.com 344*351Smax.romanov@nginx.com return NULL; 345*351Smax.romanov@nginx.com } 346*351Smax.romanov@nginx.com 347*351Smax.romanov@nginx.com nxt_router_ra_init(task, ra, ra_src->rc); 348*351Smax.romanov@nginx.com 349*351Smax.romanov@nginx.com ra->mem_pool = mp; 350167Smax.romanov@nginx.com 351167Smax.romanov@nginx.com return ra; 352167Smax.romanov@nginx.com } 353167Smax.romanov@nginx.com 354167Smax.romanov@nginx.com 355167Smax.romanov@nginx.com static void 356167Smax.romanov@nginx.com nxt_router_ra_release(nxt_task_t *task, void *obj, void *data) 357167Smax.romanov@nginx.com { 358343Smax.romanov@nginx.com nxt_req_app_link_t *ra; 359343Smax.romanov@nginx.com nxt_event_engine_t *engine; 360343Smax.romanov@nginx.com nxt_req_conn_link_t *rc; 361318Smax.romanov@nginx.com 362318Smax.romanov@nginx.com ra = obj; 363318Smax.romanov@nginx.com engine = data; 364318Smax.romanov@nginx.com 365343Smax.romanov@nginx.com if (task->thread->engine != engine) { 366343Smax.romanov@nginx.com if (ra->app_port != NULL) { 367343Smax.romanov@nginx.com ra->app_pid = ra->app_port->pid; 368318Smax.romanov@nginx.com } 369318Smax.romanov@nginx.com 370318Smax.romanov@nginx.com ra->work.handler = nxt_router_ra_release; 371318Smax.romanov@nginx.com ra->work.task = &engine->task; 372318Smax.romanov@nginx.com ra->work.next = NULL; 373318Smax.romanov@nginx.com 374318Smax.romanov@nginx.com nxt_debug(task, "ra stream #%uD post release to %p", 375318Smax.romanov@nginx.com ra->stream, engine); 376318Smax.romanov@nginx.com 377318Smax.romanov@nginx.com nxt_event_engine_post(engine, &ra->work); 378318Smax.romanov@nginx.com 379318Smax.romanov@nginx.com return; 380318Smax.romanov@nginx.com } 381318Smax.romanov@nginx.com 382343Smax.romanov@nginx.com nxt_debug(task, "ra stream #%uD release", ra->stream); 383343Smax.romanov@nginx.com 384343Smax.romanov@nginx.com rc = ra->rc; 385343Smax.romanov@nginx.com 386343Smax.romanov@nginx.com if (rc != NULL) { 387343Smax.romanov@nginx.com if (ra->app_pid != -1) { 388343Smax.romanov@nginx.com nxt_port_rpc_ex_set_peer(task, engine->port, rc, ra->app_pid); 389343Smax.romanov@nginx.com } 390343Smax.romanov@nginx.com 391343Smax.romanov@nginx.com rc->app_port = ra->app_port; 392343Smax.romanov@nginx.com 393343Smax.romanov@nginx.com ra->app_port = NULL; 394343Smax.romanov@nginx.com rc->ra = NULL; 395343Smax.romanov@nginx.com ra->rc = NULL; 396318Smax.romanov@nginx.com } 397318Smax.romanov@nginx.com 398343Smax.romanov@nginx.com if (ra->app_port != NULL) { 399343Smax.romanov@nginx.com nxt_router_app_port_release(task, ra->app_port, 0, 1); 400343Smax.romanov@nginx.com 401343Smax.romanov@nginx.com ra->app_port = NULL; 402343Smax.romanov@nginx.com } 403318Smax.romanov@nginx.com 404*351Smax.romanov@nginx.com if (ra->mem_pool != NULL) { 405*351Smax.romanov@nginx.com nxt_mp_release(ra->mem_pool, ra); 406*351Smax.romanov@nginx.com } 407318Smax.romanov@nginx.com } 408318Smax.romanov@nginx.com 409318Smax.romanov@nginx.com 410318Smax.romanov@nginx.com static void 411318Smax.romanov@nginx.com nxt_router_ra_abort(nxt_task_t *task, void *obj, void *data) 412318Smax.romanov@nginx.com { 413343Smax.romanov@nginx.com nxt_conn_t *c; 414343Smax.romanov@nginx.com nxt_req_app_link_t *ra; 415343Smax.romanov@nginx.com nxt_req_conn_link_t *rc; 416343Smax.romanov@nginx.com nxt_event_engine_t *engine; 417167Smax.romanov@nginx.com 418167Smax.romanov@nginx.com ra = obj; 419167Smax.romanov@nginx.com engine = data; 420167Smax.romanov@nginx.com 421167Smax.romanov@nginx.com if (task->thread->engine != engine) { 422318Smax.romanov@nginx.com ra->work.handler = nxt_router_ra_abort; 423167Smax.romanov@nginx.com ra->work.task = &engine->task; 424167Smax.romanov@nginx.com ra->work.next = NULL; 425167Smax.romanov@nginx.com 426318Smax.romanov@nginx.com nxt_debug(task, "ra stream #%uD post abort to %p", ra->stream, engine); 427167Smax.romanov@nginx.com 428167Smax.romanov@nginx.com nxt_event_engine_post(engine, &ra->work); 429167Smax.romanov@nginx.com 430167Smax.romanov@nginx.com return; 431167Smax.romanov@nginx.com } 432167Smax.romanov@nginx.com 433318Smax.romanov@nginx.com nxt_debug(task, "ra stream #%uD abort", ra->stream); 434318Smax.romanov@nginx.com 435343Smax.romanov@nginx.com rc = ra->rc; 436343Smax.romanov@nginx.com 437343Smax.romanov@nginx.com if (rc != NULL) { 438343Smax.romanov@nginx.com c = rc->conn; 439318Smax.romanov@nginx.com 440318Smax.romanov@nginx.com nxt_router_gen_error(task, c, 500, 441318Smax.romanov@nginx.com "Failed to start application worker"); 442343Smax.romanov@nginx.com 443343Smax.romanov@nginx.com rc->ra = NULL; 444343Smax.romanov@nginx.com ra->rc = NULL; 445343Smax.romanov@nginx.com } 446343Smax.romanov@nginx.com 447343Smax.romanov@nginx.com if (ra->app_port != NULL) { 448343Smax.romanov@nginx.com nxt_router_app_port_release(task, ra->app_port, 0, 1); 449343Smax.romanov@nginx.com 450343Smax.romanov@nginx.com ra->app_port = NULL; 451167Smax.romanov@nginx.com } 452167Smax.romanov@nginx.com 453*351Smax.romanov@nginx.com if (ra->mem_pool != NULL) { 454*351Smax.romanov@nginx.com nxt_mp_release(ra->mem_pool, ra); 455*351Smax.romanov@nginx.com } 456167Smax.romanov@nginx.com } 457167Smax.romanov@nginx.com 458167Smax.romanov@nginx.com 459345Smax.romanov@nginx.com static void 460345Smax.romanov@nginx.com nxt_router_ra_error_handler(nxt_task_t *task, void *obj, void *data) 461345Smax.romanov@nginx.com { 462345Smax.romanov@nginx.com nxt_req_app_link_t *ra; 463345Smax.romanov@nginx.com 464345Smax.romanov@nginx.com ra = obj; 465345Smax.romanov@nginx.com 466345Smax.romanov@nginx.com nxt_router_ra_error(task, ra, ra->err_code, ra->err_str); 467345Smax.romanov@nginx.com } 468345Smax.romanov@nginx.com 469345Smax.romanov@nginx.com 470345Smax.romanov@nginx.com static void 471345Smax.romanov@nginx.com nxt_router_ra_error(nxt_task_t *task, nxt_req_app_link_t *ra, int code, 472345Smax.romanov@nginx.com const char* str) 473345Smax.romanov@nginx.com { 474345Smax.romanov@nginx.com nxt_conn_t *c; 475345Smax.romanov@nginx.com nxt_req_conn_link_t *rc; 476345Smax.romanov@nginx.com nxt_event_engine_t *engine; 477345Smax.romanov@nginx.com 478345Smax.romanov@nginx.com engine = ra->work.data; 479345Smax.romanov@nginx.com 480345Smax.romanov@nginx.com if (task->thread->engine != engine) { 481345Smax.romanov@nginx.com ra->err_code = code; 482345Smax.romanov@nginx.com ra->err_str = str; 483345Smax.romanov@nginx.com 484345Smax.romanov@nginx.com ra->work.handler = nxt_router_ra_error_handler; 485345Smax.romanov@nginx.com ra->work.task = &engine->task; 486345Smax.romanov@nginx.com ra->work.next = NULL; 487345Smax.romanov@nginx.com 488345Smax.romanov@nginx.com nxt_debug(task, "ra stream #%uD post error to %p", ra->stream, engine); 489345Smax.romanov@nginx.com 490345Smax.romanov@nginx.com nxt_event_engine_post(engine, &ra->work); 491345Smax.romanov@nginx.com 492345Smax.romanov@nginx.com return; 493345Smax.romanov@nginx.com } 494345Smax.romanov@nginx.com 495345Smax.romanov@nginx.com nxt_debug(task, "ra stream #%uD error", ra->stream); 496345Smax.romanov@nginx.com 497345Smax.romanov@nginx.com rc = ra->rc; 498345Smax.romanov@nginx.com 499345Smax.romanov@nginx.com if (rc != NULL) { 500345Smax.romanov@nginx.com c = rc->conn; 501345Smax.romanov@nginx.com 502345Smax.romanov@nginx.com nxt_router_gen_error(task, c, code, str); 503345Smax.romanov@nginx.com 504345Smax.romanov@nginx.com rc->ra = NULL; 505345Smax.romanov@nginx.com ra->rc = NULL; 506345Smax.romanov@nginx.com } 507345Smax.romanov@nginx.com 508345Smax.romanov@nginx.com if (ra->app_port != NULL) { 509345Smax.romanov@nginx.com nxt_router_app_port_release(task, ra->app_port, 0, 1); 510345Smax.romanov@nginx.com 511345Smax.romanov@nginx.com ra->app_port = NULL; 512345Smax.romanov@nginx.com } 513345Smax.romanov@nginx.com 514*351Smax.romanov@nginx.com if (ra->mem_pool != NULL) { 515*351Smax.romanov@nginx.com nxt_mp_release(ra->mem_pool, ra); 516*351Smax.romanov@nginx.com } 517345Smax.romanov@nginx.com } 518345Smax.romanov@nginx.com 519345Smax.romanov@nginx.com 520343Smax.romanov@nginx.com nxt_inline void 521343Smax.romanov@nginx.com nxt_router_rc_unlink(nxt_task_t *task, nxt_req_conn_link_t *rc) 522343Smax.romanov@nginx.com { 523343Smax.romanov@nginx.com nxt_req_app_link_t *ra; 524343Smax.romanov@nginx.com 525343Smax.romanov@nginx.com if (rc->app_port != NULL) { 526343Smax.romanov@nginx.com nxt_router_app_port_release(task, rc->app_port, 0, 1); 527343Smax.romanov@nginx.com 528343Smax.romanov@nginx.com rc->app_port = NULL; 529343Smax.romanov@nginx.com } 530343Smax.romanov@nginx.com 531343Smax.romanov@nginx.com ra = rc->ra; 532343Smax.romanov@nginx.com 533343Smax.romanov@nginx.com if (ra != NULL) { 534343Smax.romanov@nginx.com rc->ra = NULL; 535343Smax.romanov@nginx.com ra->rc = NULL; 536343Smax.romanov@nginx.com 537343Smax.romanov@nginx.com nxt_thread_mutex_lock(&rc->app->mutex); 538343Smax.romanov@nginx.com 539343Smax.romanov@nginx.com if (ra->link.next != NULL) { 540343Smax.romanov@nginx.com nxt_queue_remove(&ra->link); 541343Smax.romanov@nginx.com 542343Smax.romanov@nginx.com ra->link.next = NULL; 543343Smax.romanov@nginx.com 544343Smax.romanov@nginx.com } else { 545343Smax.romanov@nginx.com ra = NULL; 546343Smax.romanov@nginx.com } 547343Smax.romanov@nginx.com 548343Smax.romanov@nginx.com nxt_thread_mutex_unlock(&rc->app->mutex); 549343Smax.romanov@nginx.com } 550343Smax.romanov@nginx.com 551343Smax.romanov@nginx.com if (ra != NULL) { 552343Smax.romanov@nginx.com nxt_router_ra_release(task, ra, ra->work.data); 553343Smax.romanov@nginx.com } 554343Smax.romanov@nginx.com 555343Smax.romanov@nginx.com if (rc->app != NULL) { 556343Smax.romanov@nginx.com nxt_router_app_use(task, rc->app, -1); 557343Smax.romanov@nginx.com 558343Smax.romanov@nginx.com rc->app = NULL; 559343Smax.romanov@nginx.com } 560343Smax.romanov@nginx.com 561346Smax.romanov@nginx.com if (rc->ap != NULL) { 562346Smax.romanov@nginx.com nxt_app_http_req_done(task, rc->ap); 563346Smax.romanov@nginx.com 564346Smax.romanov@nginx.com rc->ap = NULL; 565346Smax.romanov@nginx.com } 566346Smax.romanov@nginx.com 567343Smax.romanov@nginx.com nxt_queue_remove(&rc->link); 568343Smax.romanov@nginx.com 569343Smax.romanov@nginx.com rc->conn = NULL; 570343Smax.romanov@nginx.com } 571343Smax.romanov@nginx.com 572343Smax.romanov@nginx.com 573141Smax.romanov@nginx.com void 574141Smax.romanov@nginx.com nxt_router_new_port_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg) 575141Smax.romanov@nginx.com { 576141Smax.romanov@nginx.com nxt_port_new_port_handler(task, msg); 577141Smax.romanov@nginx.com 578192Smax.romanov@nginx.com if (msg->port_msg.stream == 0) { 579141Smax.romanov@nginx.com return; 580141Smax.romanov@nginx.com } 581141Smax.romanov@nginx.com 582347Smax.romanov@nginx.com if (msg->u.new_port == NULL || 583347Smax.romanov@nginx.com msg->u.new_port->type != NXT_PROCESS_WORKER) 584347Smax.romanov@nginx.com { 585192Smax.romanov@nginx.com msg->port_msg.type = _NXT_PORT_MSG_RPC_ERROR; 586141Smax.romanov@nginx.com } 587192Smax.romanov@nginx.com 588192Smax.romanov@nginx.com nxt_port_rpc_handler(task, msg); 589141Smax.romanov@nginx.com } 590141Smax.romanov@nginx.com 591141Smax.romanov@nginx.com 592139Sigor@sysoev.ru void 593139Sigor@sysoev.ru nxt_router_conf_data_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg) 594115Sigor@sysoev.ru { 595139Sigor@sysoev.ru size_t dump_size; 596198Sigor@sysoev.ru nxt_int_t ret; 597139Sigor@sysoev.ru nxt_buf_t *b; 598139Sigor@sysoev.ru nxt_router_temp_conf_t *tmcf; 599139Sigor@sysoev.ru 600139Sigor@sysoev.ru b = msg->buf; 601139Sigor@sysoev.ru 602139Sigor@sysoev.ru dump_size = nxt_buf_used_size(b); 603139Sigor@sysoev.ru 604139Sigor@sysoev.ru if (dump_size > 300) { 605139Sigor@sysoev.ru dump_size = 300; 60653Sigor@sysoev.ru } 60753Sigor@sysoev.ru 608139Sigor@sysoev.ru nxt_debug(task, "router conf data (%z): %*s", 609139Sigor@sysoev.ru msg->size, dump_size, b->mem.pos); 610139Sigor@sysoev.ru 611139Sigor@sysoev.ru tmcf = nxt_router_temp_conf(task); 612139Sigor@sysoev.ru if (nxt_slow_path(tmcf == NULL)) { 613139Sigor@sysoev.ru return; 61453Sigor@sysoev.ru } 61553Sigor@sysoev.ru 616139Sigor@sysoev.ru tmcf->conf->router = nxt_router; 617139Sigor@sysoev.ru tmcf->stream = msg->port_msg.stream; 618139Sigor@sysoev.ru tmcf->port = nxt_runtime_port_find(task->thread->runtime, 619198Sigor@sysoev.ru msg->port_msg.pid, 620198Sigor@sysoev.ru msg->port_msg.reply_port); 621198Sigor@sysoev.ru 622198Sigor@sysoev.ru ret = nxt_router_conf_create(task, tmcf, b->mem.pos, b->mem.free); 623198Sigor@sysoev.ru 624198Sigor@sysoev.ru if (nxt_fast_path(ret == NXT_OK)) { 625198Sigor@sysoev.ru nxt_router_conf_apply(task, tmcf, NULL); 626198Sigor@sysoev.ru 627198Sigor@sysoev.ru } else { 628198Sigor@sysoev.ru nxt_router_conf_error(task, tmcf); 629139Sigor@sysoev.ru } 63053Sigor@sysoev.ru } 63153Sigor@sysoev.ru 63253Sigor@sysoev.ru 633347Smax.romanov@nginx.com static void 634347Smax.romanov@nginx.com nxt_router_worker_remove_pid(nxt_task_t *task, nxt_port_t *port, void *data) 635347Smax.romanov@nginx.com { 636347Smax.romanov@nginx.com union { 637347Smax.romanov@nginx.com nxt_pid_t removed_pid; 638347Smax.romanov@nginx.com void *data; 639347Smax.romanov@nginx.com } u; 640347Smax.romanov@nginx.com 641347Smax.romanov@nginx.com u.data = data; 642347Smax.romanov@nginx.com 643347Smax.romanov@nginx.com nxt_port_rpc_remove_peer(task, port, u.removed_pid); 644347Smax.romanov@nginx.com } 645347Smax.romanov@nginx.com 646347Smax.romanov@nginx.com 647192Smax.romanov@nginx.com void 648192Smax.romanov@nginx.com nxt_router_remove_pid_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg) 649192Smax.romanov@nginx.com { 650347Smax.romanov@nginx.com nxt_event_engine_t *engine; 651318Smax.romanov@nginx.com 652192Smax.romanov@nginx.com nxt_port_remove_pid_handler(task, msg); 653192Smax.romanov@nginx.com 654192Smax.romanov@nginx.com if (msg->port_msg.stream == 0) { 655192Smax.romanov@nginx.com return; 656192Smax.romanov@nginx.com } 657192Smax.romanov@nginx.com 658318Smax.romanov@nginx.com nxt_queue_each(engine, &nxt_router->engines, nxt_event_engine_t, link0) 659318Smax.romanov@nginx.com { 660347Smax.romanov@nginx.com nxt_port_post(task, engine->port, nxt_router_worker_remove_pid, 661347Smax.romanov@nginx.com msg->u.data); 662318Smax.romanov@nginx.com } 663318Smax.romanov@nginx.com nxt_queue_loop; 664318Smax.romanov@nginx.com 665192Smax.romanov@nginx.com msg->port_msg.type = _NXT_PORT_MSG_RPC_ERROR; 666192Smax.romanov@nginx.com 667192Smax.romanov@nginx.com nxt_port_rpc_handler(task, msg); 668192Smax.romanov@nginx.com } 669192Smax.romanov@nginx.com 670192Smax.romanov@nginx.com 67153Sigor@sysoev.ru static nxt_router_temp_conf_t * 672139Sigor@sysoev.ru nxt_router_temp_conf(nxt_task_t *task) 67353Sigor@sysoev.ru { 67465Sigor@sysoev.ru nxt_mp_t *mp, *tmp; 67553Sigor@sysoev.ru nxt_router_conf_t *rtcf; 67653Sigor@sysoev.ru nxt_router_temp_conf_t *tmcf; 67753Sigor@sysoev.ru 67865Sigor@sysoev.ru mp = nxt_mp_create(1024, 128, 256, 32); 67953Sigor@sysoev.ru if (nxt_slow_path(mp == NULL)) { 68053Sigor@sysoev.ru return NULL; 68153Sigor@sysoev.ru } 68253Sigor@sysoev.ru 68365Sigor@sysoev.ru rtcf = nxt_mp_zget(mp, sizeof(nxt_router_conf_t)); 68453Sigor@sysoev.ru if (nxt_slow_path(rtcf == NULL)) { 68553Sigor@sysoev.ru goto fail; 68653Sigor@sysoev.ru } 68753Sigor@sysoev.ru 68853Sigor@sysoev.ru rtcf->mem_pool = mp; 68953Sigor@sysoev.ru 69065Sigor@sysoev.ru tmp = nxt_mp_create(1024, 128, 256, 32); 69153Sigor@sysoev.ru if (nxt_slow_path(tmp == NULL)) { 69253Sigor@sysoev.ru goto fail; 69353Sigor@sysoev.ru } 69453Sigor@sysoev.ru 69565Sigor@sysoev.ru tmcf = nxt_mp_zget(tmp, sizeof(nxt_router_temp_conf_t)); 69653Sigor@sysoev.ru if (nxt_slow_path(tmcf == NULL)) { 69753Sigor@sysoev.ru goto temp_fail; 69853Sigor@sysoev.ru } 69953Sigor@sysoev.ru 70053Sigor@sysoev.ru tmcf->mem_pool = tmp; 70153Sigor@sysoev.ru tmcf->conf = rtcf; 702139Sigor@sysoev.ru tmcf->count = 1; 703139Sigor@sysoev.ru tmcf->engine = task->thread->engine; 70453Sigor@sysoev.ru 70553Sigor@sysoev.ru tmcf->engines = nxt_array_create(tmcf->mem_pool, 4, 70653Sigor@sysoev.ru sizeof(nxt_router_engine_conf_t)); 70753Sigor@sysoev.ru if (nxt_slow_path(tmcf->engines == NULL)) { 70853Sigor@sysoev.ru goto temp_fail; 70953Sigor@sysoev.ru } 71053Sigor@sysoev.ru 71153Sigor@sysoev.ru nxt_queue_init(&tmcf->deleting); 71253Sigor@sysoev.ru nxt_queue_init(&tmcf->keeping); 71353Sigor@sysoev.ru nxt_queue_init(&tmcf->updating); 71453Sigor@sysoev.ru nxt_queue_init(&tmcf->pending); 71553Sigor@sysoev.ru nxt_queue_init(&tmcf->creating); 716133Sigor@sysoev.ru nxt_queue_init(&tmcf->apps); 717133Sigor@sysoev.ru nxt_queue_init(&tmcf->previous); 71853Sigor@sysoev.ru 71953Sigor@sysoev.ru return tmcf; 72053Sigor@sysoev.ru 72153Sigor@sysoev.ru temp_fail: 72253Sigor@sysoev.ru 72365Sigor@sysoev.ru nxt_mp_destroy(tmp); 72453Sigor@sysoev.ru 72553Sigor@sysoev.ru fail: 72653Sigor@sysoev.ru 72765Sigor@sysoev.ru nxt_mp_destroy(mp); 72853Sigor@sysoev.ru 72953Sigor@sysoev.ru return NULL; 73053Sigor@sysoev.ru } 73153Sigor@sysoev.ru 73253Sigor@sysoev.ru 733198Sigor@sysoev.ru static void 734198Sigor@sysoev.ru nxt_router_conf_apply(nxt_task_t *task, void *obj, void *data) 735139Sigor@sysoev.ru { 736139Sigor@sysoev.ru nxt_int_t ret; 737139Sigor@sysoev.ru nxt_router_t *router; 738139Sigor@sysoev.ru nxt_runtime_t *rt; 739198Sigor@sysoev.ru nxt_queue_link_t *qlk; 740198Sigor@sysoev.ru nxt_socket_conf_t *skcf; 741198Sigor@sysoev.ru nxt_router_temp_conf_t *tmcf; 742139Sigor@sysoev.ru const nxt_event_interface_t *interface; 743139Sigor@sysoev.ru 744198Sigor@sysoev.ru tmcf = obj; 745198Sigor@sysoev.ru 746198Sigor@sysoev.ru qlk = nxt_queue_first(&tmcf->pending); 747198Sigor@sysoev.ru 748198Sigor@sysoev.ru if (qlk != nxt_queue_tail(&tmcf->pending)) { 749198Sigor@sysoev.ru nxt_queue_remove(qlk); 750198Sigor@sysoev.ru nxt_queue_insert_tail(&tmcf->creating, qlk); 751198Sigor@sysoev.ru 752198Sigor@sysoev.ru skcf = nxt_queue_link_data(qlk, nxt_socket_conf_t, link); 753198Sigor@sysoev.ru 754198Sigor@sysoev.ru nxt_router_listen_socket_rpc_create(task, tmcf, skcf); 755198Sigor@sysoev.ru 756198Sigor@sysoev.ru return; 757139Sigor@sysoev.ru } 758139Sigor@sysoev.ru 759139Sigor@sysoev.ru rt = task->thread->runtime; 760139Sigor@sysoev.ru 761139Sigor@sysoev.ru interface = nxt_service_get(rt->services, "engine", NULL); 762139Sigor@sysoev.ru 763198Sigor@sysoev.ru router = tmcf->conf->router; 764198Sigor@sysoev.ru 765139Sigor@sysoev.ru ret = nxt_router_engines_create(task, router, tmcf, interface); 766139Sigor@sysoev.ru if (nxt_slow_path(ret != NXT_OK)) { 767198Sigor@sysoev.ru goto fail; 768139Sigor@sysoev.ru } 769139Sigor@sysoev.ru 770139Sigor@sysoev.ru ret = nxt_router_threads_create(task, rt, tmcf); 771139Sigor@sysoev.ru if (nxt_slow_path(ret != NXT_OK)) { 772198Sigor@sysoev.ru goto fail; 773139Sigor@sysoev.ru } 774139Sigor@sysoev.ru 775343Smax.romanov@nginx.com nxt_router_apps_sort(task, router, tmcf); 776139Sigor@sysoev.ru 777315Sigor@sysoev.ru nxt_router_engines_post(router, tmcf); 778139Sigor@sysoev.ru 779139Sigor@sysoev.ru nxt_queue_add(&router->sockets, &tmcf->updating); 780139Sigor@sysoev.ru nxt_queue_add(&router->sockets, &tmcf->creating); 781139Sigor@sysoev.ru 782198Sigor@sysoev.ru nxt_router_conf_ready(task, tmcf); 783198Sigor@sysoev.ru 784198Sigor@sysoev.ru return; 785198Sigor@sysoev.ru 786198Sigor@sysoev.ru fail: 787198Sigor@sysoev.ru 788198Sigor@sysoev.ru nxt_router_conf_error(task, tmcf); 789198Sigor@sysoev.ru 790198Sigor@sysoev.ru return; 791139Sigor@sysoev.ru } 792139Sigor@sysoev.ru 793139Sigor@sysoev.ru 794139Sigor@sysoev.ru static void 795139Sigor@sysoev.ru nxt_router_conf_wait(nxt_task_t *task, void *obj, void *data) 796139Sigor@sysoev.ru { 797153Sigor@sysoev.ru nxt_joint_job_t *job; 798153Sigor@sysoev.ru 799153Sigor@sysoev.ru job = obj; 800153Sigor@sysoev.ru 801198Sigor@sysoev.ru nxt_router_conf_ready(task, job->tmcf); 802139Sigor@sysoev.ru } 803139Sigor@sysoev.ru 804139Sigor@sysoev.ru 805139Sigor@sysoev.ru static void 806198Sigor@sysoev.ru nxt_router_conf_ready(nxt_task_t *task, nxt_router_temp_conf_t *tmcf) 807139Sigor@sysoev.ru { 808139Sigor@sysoev.ru nxt_debug(task, "temp conf count:%D", tmcf->count); 809139Sigor@sysoev.ru