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 79115Sigor@sysoev.ru static nxt_int_t nxt_router_conf_create(nxt_task_t *task, 80115Sigor@sysoev.ru nxt_router_temp_conf_t *tmcf, u_char *start, u_char *end); 81133Sigor@sysoev.ru static nxt_app_t *nxt_router_app_find(nxt_queue_t *queue, nxt_str_t *name); 82133Sigor@sysoev.ru static nxt_app_t *nxt_router_listener_application(nxt_router_temp_conf_t *tmcf, 83133Sigor@sysoev.ru nxt_str_t *name); 84198Sigor@sysoev.ru static void nxt_router_listen_socket_rpc_create(nxt_task_t *task, 85198Sigor@sysoev.ru nxt_router_temp_conf_t *tmcf, nxt_socket_conf_t *skcf); 86198Sigor@sysoev.ru static void nxt_router_listen_socket_ready(nxt_task_t *task, 87198Sigor@sysoev.ru nxt_port_recv_msg_t *msg, void *data); 88198Sigor@sysoev.ru static void nxt_router_listen_socket_error(nxt_task_t *task, 89198Sigor@sysoev.ru nxt_port_recv_msg_t *msg, void *data); 90*359Sigor@sysoev.ru static nxt_socket_conf_t *nxt_router_socket_conf(nxt_task_t *task, 91*359Sigor@sysoev.ru nxt_router_temp_conf_t *tmcf, nxt_str_t *name); 92*359Sigor@sysoev.ru static nxt_int_t nxt_router_listen_socket_find(nxt_router_temp_conf_t *tmcf, 93*359Sigor@sysoev.ru nxt_socket_conf_t *nskcf, 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); 104154Sigor@sysoev.ru static nxt_int_t nxt_router_engine_joints_create(nxt_router_temp_conf_t *tmcf, 105154Sigor@sysoev.ru nxt_router_engine_conf_t *recf, nxt_queue_t *sockets, 106154Sigor@sysoev.ru nxt_work_handler_t handler); 107313Sigor@sysoev.ru static nxt_int_t nxt_router_engine_quit(nxt_router_temp_conf_t *tmcf, 108313Sigor@sysoev.ru nxt_router_engine_conf_t *recf); 109139Sigor@sysoev.ru static nxt_int_t nxt_router_engine_joints_delete(nxt_router_temp_conf_t *tmcf, 110139Sigor@sysoev.ru nxt_router_engine_conf_t *recf, nxt_queue_t *sockets); 11153Sigor@sysoev.ru 11253Sigor@sysoev.ru static nxt_int_t nxt_router_threads_create(nxt_task_t *task, nxt_runtime_t *rt, 11353Sigor@sysoev.ru nxt_router_temp_conf_t *tmcf); 11453Sigor@sysoev.ru static nxt_int_t nxt_router_thread_create(nxt_task_t *task, nxt_runtime_t *rt, 11553Sigor@sysoev.ru nxt_event_engine_t *engine); 116343Smax.romanov@nginx.com static void nxt_router_apps_sort(nxt_task_t *task, nxt_router_t *router, 117133Sigor@sysoev.ru nxt_router_temp_conf_t *tmcf); 11853Sigor@sysoev.ru 119315Sigor@sysoev.ru static void nxt_router_engines_post(nxt_router_t *router, 120315Sigor@sysoev.ru nxt_router_temp_conf_t *tmcf); 121315Sigor@sysoev.ru static void nxt_router_engine_post(nxt_event_engine_t *engine, 122315Sigor@sysoev.ru nxt_work_t *jobs); 12353Sigor@sysoev.ru 12453Sigor@sysoev.ru static void nxt_router_thread_start(void *data); 12553Sigor@sysoev.ru static void nxt_router_listen_socket_create(nxt_task_t *task, void *obj, 12653Sigor@sysoev.ru void *data); 12753Sigor@sysoev.ru static void nxt_router_listen_socket_update(nxt_task_t *task, void *obj, 12853Sigor@sysoev.ru void *data); 12953Sigor@sysoev.ru static void nxt_router_listen_socket_delete(nxt_task_t *task, void *obj, 13053Sigor@sysoev.ru void *data); 131313Sigor@sysoev.ru static void nxt_router_worker_thread_quit(nxt_task_t *task, void *obj, 132313Sigor@sysoev.ru void *data); 13353Sigor@sysoev.ru static void nxt_router_listen_socket_close(nxt_task_t *task, void *obj, 13453Sigor@sysoev.ru void *data); 13553Sigor@sysoev.ru static void nxt_router_thread_exit_handler(nxt_task_t *task, void *obj, 13653Sigor@sysoev.ru void *data); 137*359Sigor@sysoev.ru static void nxt_router_listen_socket_release(nxt_task_t *task, 138*359Sigor@sysoev.ru nxt_socket_conf_t *skcf); 13953Sigor@sysoev.ru static void nxt_router_conf_release(nxt_task_t *task, 14053Sigor@sysoev.ru nxt_socket_conf_joint_t *joint); 14153Sigor@sysoev.ru 142343Smax.romanov@nginx.com static void nxt_router_app_port_ready(nxt_task_t *task, 143343Smax.romanov@nginx.com nxt_port_recv_msg_t *msg, void *data); 144343Smax.romanov@nginx.com static void nxt_router_app_port_error(nxt_task_t *task, 145343Smax.romanov@nginx.com nxt_port_recv_msg_t *msg, void *data); 146343Smax.romanov@nginx.com 147343Smax.romanov@nginx.com static nxt_port_t * nxt_router_app_get_idle_port(nxt_app_t *app); 148343Smax.romanov@nginx.com static void nxt_router_app_port_release(nxt_task_t *task, nxt_port_t *port, 149343Smax.romanov@nginx.com uint32_t request_failed, uint32_t got_response); 150141Smax.romanov@nginx.com 15153Sigor@sysoev.ru static void nxt_router_conn_init(nxt_task_t *task, void *obj, void *data); 15253Sigor@sysoev.ru static void nxt_router_conn_http_header_parse(nxt_task_t *task, void *obj, 15353Sigor@sysoev.ru void *data); 154*359Sigor@sysoev.ru static nxt_sockaddr_t *nxt_router_local_addr(nxt_task_t *task, nxt_conn_t *c); 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 305351Smax.romanov@nginx.com nxt_inline void 306351Smax.romanov@nginx.com nxt_router_ra_init(nxt_task_t *task, nxt_req_app_link_t *ra, 307351Smax.romanov@nginx.com nxt_req_conn_link_t *rc) 308167Smax.romanov@nginx.com { 309318Smax.romanov@nginx.com nxt_event_engine_t *engine; 310351Smax.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; 320351Smax.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; 326351Smax.romanov@nginx.com } 327351Smax.romanov@nginx.com 328351Smax.romanov@nginx.com 329351Smax.romanov@nginx.com nxt_inline nxt_req_app_link_t * 330351Smax.romanov@nginx.com nxt_router_ra_create(nxt_task_t *task, nxt_req_app_link_t *ra_src) 331351Smax.romanov@nginx.com { 332351Smax.romanov@nginx.com nxt_mp_t *mp; 333351Smax.romanov@nginx.com nxt_req_app_link_t *ra; 334351Smax.romanov@nginx.com 335351Smax.romanov@nginx.com mp = ra_src->ap->mem_pool; 336351Smax.romanov@nginx.com 337351Smax.romanov@nginx.com ra = nxt_mp_retain(mp, sizeof(nxt_req_app_link_t)); 338351Smax.romanov@nginx.com 339351Smax.romanov@nginx.com if (nxt_slow_path(ra == NULL)) { 340351Smax.romanov@nginx.com 341351Smax.romanov@nginx.com ra_src->rc->ra = NULL; 342351Smax.romanov@nginx.com ra_src->rc = NULL; 343351Smax.romanov@nginx.com 344351Smax.romanov@nginx.com return NULL; 345351Smax.romanov@nginx.com } 346351Smax.romanov@nginx.com 347351Smax.romanov@nginx.com nxt_router_ra_init(task, ra, ra_src->rc); 348351Smax.romanov@nginx.com 349351Smax.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 404351Smax.romanov@nginx.com if (ra->mem_pool != NULL) { 405351Smax.romanov@nginx.com nxt_mp_release(ra->mem_pool, ra); 406351Smax.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 453351Smax.romanov@nginx.com if (ra->mem_pool != NULL) { 454351Smax.romanov@nginx.com nxt_mp_release(ra->mem_pool, ra); 455351Smax.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 514351Smax.romanov@nginx.com if (ra->mem_pool != NULL) { 515351Smax.romanov@nginx.com nxt_mp_release(ra->mem_pool, ra); 516351Smax.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 { 595198Sigor@sysoev.ru nxt_int_t ret; 596139Sigor@sysoev.ru nxt_buf_t *b; 597139Sigor@sysoev.ru nxt_router_temp_conf_t *tmcf; 598139Sigor@sysoev.ru 599139Sigor@sysoev.ru tmcf = nxt_router_temp_conf(task); 600139Sigor@sysoev.ru if (nxt_slow_path(tmcf == NULL)) { 601139Sigor@sysoev.ru return; 60253Sigor@sysoev.ru } 60353Sigor@sysoev.ru 604352Smax.romanov@nginx.com b = nxt_buf_chk_make_plain(tmcf->conf->mem_pool, msg->buf, msg->size); 605352Smax.romanov@nginx.com 606352Smax.romanov@nginx.com nxt_assert(b != NULL); 607352Smax.romanov@nginx.com 608139Sigor@sysoev.ru tmcf->conf->router = nxt_router; 609139Sigor@sysoev.ru tmcf->stream = msg->port_msg.stream; 610139Sigor@sysoev.ru tmcf->port = nxt_runtime_port_find(task->thread->runtime, 611198Sigor@sysoev.ru msg->port_msg.pid, 612198Sigor@sysoev.ru msg->port_msg.reply_port); 613198Sigor@sysoev.ru 614198Sigor@sysoev.ru ret = nxt_router_conf_create(task, tmcf, b->mem.pos, b->mem.free); 615198Sigor@sysoev.ru 616198Sigor@sysoev.ru if (nxt_fast_path(ret == NXT_OK)) { 617198Sigor@sysoev.ru nxt_router_conf_apply(task, tmcf, NULL); 618198Sigor@sysoev.ru 619198Sigor@sysoev.ru } else { 620198Sigor@sysoev.ru nxt_router_conf_error(task, tmcf); 621139Sigor@sysoev.ru } 62253Sigor@sysoev.ru } 62353Sigor@sysoev.ru 62453Sigor@sysoev.ru 625347Smax.romanov@nginx.com static void 626347Smax.romanov@nginx.com nxt_router_worker_remove_pid(nxt_task_t *task, nxt_port_t *port, void *data) 627347Smax.romanov@nginx.com { 628347Smax.romanov@nginx.com union { 629347Smax.romanov@nginx.com nxt_pid_t removed_pid; 630347Smax.romanov@nginx.com void *data; 631347Smax.romanov@nginx.com } u; 632347Smax.romanov@nginx.com 633347Smax.romanov@nginx.com u.data = data; 634347Smax.romanov@nginx.com 635347Smax.romanov@nginx.com nxt_port_rpc_remove_peer(task, port, u.removed_pid); 636347Smax.romanov@nginx.com } 637347Smax.romanov@nginx.com 638347Smax.romanov@nginx.com 639192Smax.romanov@nginx.com void 640192Smax.romanov@nginx.com nxt_router_remove_pid_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg) 641192Smax.romanov@nginx.com { 642347Smax.romanov@nginx.com nxt_event_engine_t *engine; 643318Smax.romanov@nginx.com 644192Smax.romanov@nginx.com nxt_port_remove_pid_handler(task, msg); 645192Smax.romanov@nginx.com 646192Smax.romanov@nginx.com if (msg->port_msg.stream == 0) { 647192Smax.romanov@nginx.com return; 648192Smax.romanov@nginx.com } 649192Smax.romanov@nginx.com 650318Smax.romanov@nginx.com nxt_queue_each(engine, &nxt_router->engines, nxt_event_engine_t, link0) 651318Smax.romanov@nginx.com { 652347Smax.romanov@nginx.com nxt_port_post(task, engine->port, nxt_router_worker_remove_pid, 653347Smax.romanov@nginx.com msg->u.data); 654318Smax.romanov@nginx.com } 655318Smax.romanov@nginx.com nxt_queue_loop; 656318Smax.romanov@nginx.com 657192Smax.romanov@nginx.com msg->port_msg.type = _NXT_PORT_MSG_RPC_ERROR; 658192Smax.romanov@nginx.com 659192Smax.romanov@nginx.com nxt_port_rpc_handler(task, msg); 660192Smax.romanov@nginx.com } 661192Smax.romanov@nginx.com 662192Smax.romanov@nginx.com 66353Sigor@sysoev.ru static nxt_router_temp_conf_t * 664139Sigor@sysoev.ru nxt_router_temp_conf(nxt_task_t *task) 66553Sigor@sysoev.ru { 66665Sigor@sysoev.ru nxt_mp_t *mp, *tmp; 66753Sigor@sysoev.ru nxt_router_conf_t *rtcf; 66853Sigor@sysoev.ru nxt_router_temp_conf_t *tmcf; 66953Sigor@sysoev.ru 67065Sigor@sysoev.ru mp = nxt_mp_create(1024, 128, 256, 32); 67153Sigor@sysoev.ru if (nxt_slow_path(mp == NULL)) { 67253Sigor@sysoev.ru return NULL; 67353Sigor@sysoev.ru } 67453Sigor@sysoev.ru 67565Sigor@sysoev.ru rtcf = nxt_mp_zget(mp, sizeof(nxt_router_conf_t)); 67653Sigor@sysoev.ru if (nxt_slow_path(rtcf == NULL)) { 67753Sigor@sysoev.ru goto fail; 67853Sigor@sysoev.ru } 67953Sigor@sysoev.ru 68053Sigor@sysoev.ru rtcf->mem_pool = mp; 68153Sigor@sysoev.ru 68265Sigor@sysoev.ru tmp = nxt_mp_create(1024, 128, 256, 32); 68353Sigor@sysoev.ru if (nxt_slow_path(tmp == NULL)) { 68453Sigor@sysoev.ru goto fail; 68553Sigor@sysoev.ru } 68653Sigor@sysoev.ru 68765Sigor@sysoev.ru tmcf = nxt_mp_zget(tmp, sizeof(nxt_router_temp_conf_t)); 68853Sigor@sysoev.ru if (nxt_slow_path(tmcf == NULL)) { 68953Sigor@sysoev.ru goto temp_fail; 69053Sigor@sysoev.ru } 69153Sigor@sysoev.ru 69253Sigor@sysoev.ru tmcf->mem_pool = tmp; 69353Sigor@sysoev.ru tmcf->conf = rtcf; 694139Sigor@sysoev.ru tmcf->count = 1; 695139Sigor@sysoev.ru tmcf->engine = task->thread->engine; 69653Sigor@sysoev.ru 69753Sigor@sysoev.ru tmcf->engines = nxt_array_create(tmcf->mem_pool, 4, 69853Sigor@sysoev.ru sizeof(nxt_router_engine_conf_t)); 69953Sigor@sysoev.ru if (nxt_slow_path(tmcf->engines == NULL)) { 70053Sigor@sysoev.ru goto temp_fail; 70153Sigor@sysoev.ru } 70253Sigor@sysoev.ru 70353Sigor@sysoev.ru nxt_queue_init(&tmcf->deleting); 70453Sigor@sysoev.ru nxt_queue_init(&tmcf->keeping); 70553Sigor@sysoev.ru nxt_queue_init(&tmcf->updating); 70653Sigor@sysoev.ru nxt_queue_init(&tmcf->pending); 70753Sigor@sysoev.ru nxt_queue_init(&tmcf->creating); 708133Sigor@sysoev.ru nxt_queue_init(&tmcf->apps); 709133Sigor@sysoev.ru nxt_queue_init(&tmcf->previous); 71053Sigor@sysoev.ru 71153Sigor@sysoev.ru return tmcf; 71253Sigor@sysoev.ru 71353Sigor@sysoev.ru temp_fail: 71453Sigor@sysoev.ru 71565Sigor@sysoev.ru nxt_mp_destroy(tmp); 71653Sigor@sysoev.ru 71753Sigor@sysoev.ru fail: 71853Sigor@sysoev.ru 71965Sigor@sysoev.ru nxt_mp_destroy(mp); 72053Sigor@sysoev.ru 72153Sigor@sysoev.ru return NULL; 72253Sigor@sysoev.ru } 72353Sigor@sysoev.ru 72453Sigor@sysoev.ru 725198Sigor@sysoev.ru static void 726198Sigor@sysoev.ru nxt_router_conf_apply(nxt_task_t *task, void *obj, void *data) 727139Sigor@sysoev.ru { 728139Sigor@sysoev.ru nxt_int_t ret; 729139Sigor@sysoev.ru nxt_router_t *router; 730139Sigor@sysoev.ru nxt_runtime_t *rt; 731198Sigor@sysoev.ru nxt_queue_link_t *qlk; 732198Sigor@sysoev.ru nxt_socket_conf_t *skcf; 733198Sigor@sysoev.ru nxt_router_temp_conf_t *tmcf; 734139Sigor@sysoev.ru const nxt_event_interface_t *interface; 735139Sigor@sysoev.ru 736198Sigor@sysoev.ru tmcf = obj; 737198Sigor@sysoev.ru 738198Sigor@sysoev.ru qlk = nxt_queue_first(&tmcf->pending); 739198Sigor@sysoev.ru 740198Sigor@sysoev.ru if (qlk != nxt_queue_tail(&tmcf->pending)) { 741198Sigor@sysoev.ru nxt_queue_remove(qlk); 742198Sigor@sysoev.ru nxt_queue_insert_tail(&tmcf->creating, qlk); 743198Sigor@sysoev.ru 744198Sigor@sysoev.ru skcf = nxt_queue_link_data(qlk, nxt_socket_conf_t, link); 745198Sigor@sysoev.ru 746198Sigor@sysoev.ru nxt_router_listen_socket_rpc_create(task, tmcf, skcf); 747198Sigor@sysoev.ru 748198Sigor@sysoev.ru return; 749139Sigor@sysoev.ru } 750139Sigor@sysoev.ru 751139Sigor@sysoev.ru rt = task->thread->runtime; 752139Sigor@sysoev.ru 753139Sigor@sysoev.ru interface = nxt_service_get(rt->services, "engine", NULL); 754139Sigor@sysoev.ru 755198Sigor@sysoev.ru router = tmcf->conf->router; 756198Sigor@sysoev.ru 757139Sigor@sysoev.ru ret = nxt_router_engines_create(task, router, tmcf, interface); 758139Sigor@sysoev.ru if (nxt_slow_path(ret != NXT_OK)) { 759198Sigor@sysoev.ru goto fail; 760139Sigor@sysoev.ru } 761139Sigor@sysoev.ru 762139Sigor@sysoev.ru ret = nxt_router_threads_create(task, rt, tmcf); 763139Sigor@sysoev.ru if (nxt_slow_path(ret != NXT_OK)) { 764198Sigor@sysoev.ru goto fail; 765139Sigor@sysoev.ru } 766139Sigor@sysoev.ru 767343Smax.romanov@nginx.com nxt_router_apps_sort(task, router, tmcf); 768139Sigor@sysoev.ru 769315Sigor@sysoev.ru nxt_router_engines_post(router, tmcf); 770139Sigor@sysoev.ru 771139Sigor@sysoev.ru nxt_queue_add(&router->sockets, &tmcf->updating); 772139Sigor@sysoev.ru nxt_queue_add(&router->sockets, &tmcf->creating); 773139Sigor@sysoev.ru 774198Sigor@sysoev.ru nxt_router_conf_ready(task, tmcf); 775198Sigor@sysoev.ru 776198Sigor@sysoev.ru return; 777198Sigor@sysoev.ru 778198Sigor@sysoev.ru fail: 779198Sigor@sysoev.ru 780198Sigor@sysoev.ru nxt_router_conf_error(task, tmcf); 781198Sigor@sysoev.ru 782198Sigor@sysoev.ru return; 783139Sigor@sysoev.ru } 784139Sigor@sysoev.ru 785139Sigor@sysoev.ru 786139Sigor@sysoev.ru static void 787139Sigor@sysoev.ru nxt_router_conf_wait(nxt_task_t *task, void *obj, void *data) 788139Sigor@sysoev.ru { 789153Sigor@sysoev.ru nxt_joint_job_t *job; 790153Sigor@sysoev.ru 791153Sigor@sysoev.ru job = obj; 792153Sigor@sysoev.ru 793198Sigor@sysoev.ru nxt_router_conf_ready(task, job->tmcf); 794139Sigor@sysoev.ru } 795139Sigor@sysoev.ru 796139Sigor@sysoev.ru 797139Sigor@sysoev.ru static void 798198Sigor@sysoev.ru nxt_router_conf_ready(nxt_task_t *task, nxt_router_temp_conf_t *tmcf) 799139Sigor@sysoev.ru { 800139Sigor@sysoev.ru nxt_debug(task, "temp conf count:%D", tmcf->count); 801139Sigor@sysoev.ru 802139Sigor@sysoev.ru if (--tmcf->count == 0) { 803193Smax.romanov@nginx.com nxt_router_conf_send(task, tmcf, NXT_PORT_MSG_RPC_READY_LAST); 804139Sigor@sysoev.ru } 805139Sigor@sysoev.ru } 806139Sigor@sysoev.ru 807