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; 16*427Smax.romanov@nginx.com nxt_msec_t res_timeout; 17318Smax.romanov@nginx.com uint32_t requests; 18318Smax.romanov@nginx.com nxt_conf_value_t *limits_value; 19133Sigor@sysoev.ru } nxt_router_app_conf_t; 20133Sigor@sysoev.ru 21133Sigor@sysoev.ru 22133Sigor@sysoev.ru typedef struct { 23133Sigor@sysoev.ru nxt_str_t application; 24115Sigor@sysoev.ru } nxt_router_listener_conf_t; 25115Sigor@sysoev.ru 26115Sigor@sysoev.ru 27423Smax.romanov@nginx.com typedef struct nxt_msg_info_s { 28423Smax.romanov@nginx.com nxt_buf_t *buf; 29423Smax.romanov@nginx.com nxt_port_mmap_tracking_t tracking; 30423Smax.romanov@nginx.com nxt_work_handler_t completion_handler; 31423Smax.romanov@nginx.com } nxt_msg_info_t; 32423Smax.romanov@nginx.com 33423Smax.romanov@nginx.com 34167Smax.romanov@nginx.com typedef struct nxt_req_app_link_s nxt_req_app_link_t; 35141Smax.romanov@nginx.com 36141Smax.romanov@nginx.com 37318Smax.romanov@nginx.com typedef struct { 38318Smax.romanov@nginx.com uint32_t stream; 39318Smax.romanov@nginx.com nxt_conn_t *conn; 40343Smax.romanov@nginx.com nxt_app_t *app; 41318Smax.romanov@nginx.com nxt_port_t *app_port; 42346Smax.romanov@nginx.com nxt_app_parse_ctx_t *ap; 43423Smax.romanov@nginx.com nxt_msg_info_t msg_info; 44318Smax.romanov@nginx.com nxt_req_app_link_t *ra; 45318Smax.romanov@nginx.com 46318Smax.romanov@nginx.com nxt_queue_link_t link; /* for nxt_conn_t.requests */ 47318Smax.romanov@nginx.com } nxt_req_conn_link_t; 48318Smax.romanov@nginx.com 49318Smax.romanov@nginx.com 50167Smax.romanov@nginx.com struct nxt_req_app_link_s { 51318Smax.romanov@nginx.com uint32_t stream; 52425Smax.romanov@nginx.com nxt_atomic_t use_count; 53167Smax.romanov@nginx.com nxt_port_t *app_port; 54167Smax.romanov@nginx.com nxt_port_t *reply_port; 55167Smax.romanov@nginx.com nxt_app_parse_ctx_t *ap; 56423Smax.romanov@nginx.com nxt_msg_info_t msg_info; 57167Smax.romanov@nginx.com nxt_req_conn_link_t *rc; 58167Smax.romanov@nginx.com 59*427Smax.romanov@nginx.com nxt_nsec_t res_time; 60*427Smax.romanov@nginx.com 61425Smax.romanov@nginx.com nxt_queue_link_t link_app_requests; /* for nxt_app_t.requests */ 62425Smax.romanov@nginx.com nxt_queue_link_t link_port_pending; /* for nxt_port_t.pending_requests */ 63*427Smax.romanov@nginx.com nxt_queue_link_t link_app_pending; /* for nxt_app_t.pending */ 64167Smax.romanov@nginx.com 65167Smax.romanov@nginx.com nxt_mp_t *mem_pool; 66167Smax.romanov@nginx.com nxt_work_t work; 67345Smax.romanov@nginx.com 68345Smax.romanov@nginx.com int err_code; 69345Smax.romanov@nginx.com const char *err_str; 70167Smax.romanov@nginx.com }; 71167Smax.romanov@nginx.com 72167Smax.romanov@nginx.com 73198Sigor@sysoev.ru typedef struct { 74198Sigor@sysoev.ru nxt_socket_conf_t *socket_conf; 75198Sigor@sysoev.ru nxt_router_temp_conf_t *temp_conf; 76198Sigor@sysoev.ru } nxt_socket_rpc_t; 77198Sigor@sysoev.ru 78198Sigor@sysoev.ru 79*427Smax.romanov@nginx.com struct nxt_port_select_state_s { 80*427Smax.romanov@nginx.com nxt_app_t *app; 81*427Smax.romanov@nginx.com nxt_req_app_link_t *ra; 82*427Smax.romanov@nginx.com 83*427Smax.romanov@nginx.com nxt_port_t *failed_port; 84*427Smax.romanov@nginx.com int failed_port_use_delta; 85*427Smax.romanov@nginx.com 86*427Smax.romanov@nginx.com nxt_bool_t can_start_worker; 87*427Smax.romanov@nginx.com nxt_req_app_link_t *shared_ra; 88*427Smax.romanov@nginx.com nxt_port_t *port; 89*427Smax.romanov@nginx.com }; 90*427Smax.romanov@nginx.com 91*427Smax.romanov@nginx.com typedef struct nxt_port_select_state_s nxt_port_select_state_t; 92*427Smax.romanov@nginx.com 93*427Smax.romanov@nginx.com static void nxt_router_port_select(nxt_task_t *task, 94*427Smax.romanov@nginx.com nxt_port_select_state_t *state); 95*427Smax.romanov@nginx.com 96*427Smax.romanov@nginx.com static nxt_int_t nxt_router_port_post_select(nxt_task_t *task, 97*427Smax.romanov@nginx.com nxt_port_select_state_t *state); 98*427Smax.romanov@nginx.com 99343Smax.romanov@nginx.com static nxt_int_t nxt_router_start_worker(nxt_task_t *task, nxt_app_t *app); 100343Smax.romanov@nginx.com 101425Smax.romanov@nginx.com nxt_inline void 102425Smax.romanov@nginx.com nxt_router_ra_inc_use(nxt_req_app_link_t *ra) 103425Smax.romanov@nginx.com { 104425Smax.romanov@nginx.com nxt_atomic_fetch_add(&ra->use_count, 1); 105425Smax.romanov@nginx.com } 106425Smax.romanov@nginx.com 107425Smax.romanov@nginx.com nxt_inline void 108425Smax.romanov@nginx.com nxt_router_ra_dec_use(nxt_req_app_link_t *ra) 109425Smax.romanov@nginx.com { 110425Smax.romanov@nginx.com int c; 111425Smax.romanov@nginx.com 112425Smax.romanov@nginx.com c = nxt_atomic_fetch_add(&ra->use_count, -1); 113425Smax.romanov@nginx.com 114425Smax.romanov@nginx.com nxt_assert(c > 1); 115425Smax.romanov@nginx.com } 116425Smax.romanov@nginx.com 117425Smax.romanov@nginx.com static void nxt_router_ra_use(nxt_task_t *task, nxt_req_app_link_t *ra, int i); 118425Smax.romanov@nginx.com 119139Sigor@sysoev.ru static nxt_router_temp_conf_t *nxt_router_temp_conf(nxt_task_t *task); 120198Sigor@sysoev.ru static void nxt_router_conf_apply(nxt_task_t *task, void *obj, void *data); 121198Sigor@sysoev.ru static void nxt_router_conf_ready(nxt_task_t *task, 122139Sigor@sysoev.ru nxt_router_temp_conf_t *tmcf); 123139Sigor@sysoev.ru static void nxt_router_conf_error(nxt_task_t *task, 124139Sigor@sysoev.ru nxt_router_temp_conf_t *tmcf); 125139Sigor@sysoev.ru static void nxt_router_conf_send(nxt_task_t *task, 126193Smax.romanov@nginx.com nxt_router_temp_conf_t *tmcf, nxt_port_msg_type_t type); 12753Sigor@sysoev.ru 128115Sigor@sysoev.ru static nxt_int_t nxt_router_conf_create(nxt_task_t *task, 129115Sigor@sysoev.ru nxt_router_temp_conf_t *tmcf, u_char *start, u_char *end); 130133Sigor@sysoev.ru static nxt_app_t *nxt_router_app_find(nxt_queue_t *queue, nxt_str_t *name); 131133Sigor@sysoev.ru static nxt_app_t *nxt_router_listener_application(nxt_router_temp_conf_t *tmcf, 132133Sigor@sysoev.ru nxt_str_t *name); 133198Sigor@sysoev.ru static void nxt_router_listen_socket_rpc_create(nxt_task_t *task, 134198Sigor@sysoev.ru nxt_router_temp_conf_t *tmcf, nxt_socket_conf_t *skcf); 135198Sigor@sysoev.ru static void nxt_router_listen_socket_ready(nxt_task_t *task, 136198Sigor@sysoev.ru nxt_port_recv_msg_t *msg, void *data); 137198Sigor@sysoev.ru static void nxt_router_listen_socket_error(nxt_task_t *task, 138198Sigor@sysoev.ru nxt_port_recv_msg_t *msg, void *data); 139359Sigor@sysoev.ru static nxt_socket_conf_t *nxt_router_socket_conf(nxt_task_t *task, 140359Sigor@sysoev.ru nxt_router_temp_conf_t *tmcf, nxt_str_t *name); 141359Sigor@sysoev.ru static nxt_int_t nxt_router_listen_socket_find(nxt_router_temp_conf_t *tmcf, 142359Sigor@sysoev.ru nxt_socket_conf_t *nskcf, nxt_sockaddr_t *sa); 14353Sigor@sysoev.ru 14453Sigor@sysoev.ru static nxt_int_t nxt_router_engines_create(nxt_task_t *task, 14553Sigor@sysoev.ru nxt_router_t *router, nxt_router_temp_conf_t *tmcf, 14653Sigor@sysoev.ru const nxt_event_interface_t *interface); 147115Sigor@sysoev.ru static nxt_int_t nxt_router_engine_conf_create(nxt_router_temp_conf_t *tmcf, 148115Sigor@sysoev.ru nxt_router_engine_conf_t *recf); 149115Sigor@sysoev.ru static nxt_int_t nxt_router_engine_conf_update(nxt_router_temp_conf_t *tmcf, 150115Sigor@sysoev.ru nxt_router_engine_conf_t *recf); 151115Sigor@sysoev.ru static nxt_int_t nxt_router_engine_conf_delete(nxt_router_temp_conf_t *tmcf, 152115Sigor@sysoev.ru nxt_router_engine_conf_t *recf); 153154Sigor@sysoev.ru static nxt_int_t nxt_router_engine_joints_create(nxt_router_temp_conf_t *tmcf, 154154Sigor@sysoev.ru nxt_router_engine_conf_t *recf, nxt_queue_t *sockets, 155154Sigor@sysoev.ru nxt_work_handler_t handler); 156313Sigor@sysoev.ru static nxt_int_t nxt_router_engine_quit(nxt_router_temp_conf_t *tmcf, 157313Sigor@sysoev.ru nxt_router_engine_conf_t *recf); 158139Sigor@sysoev.ru static nxt_int_t nxt_router_engine_joints_delete(nxt_router_temp_conf_t *tmcf, 159139Sigor@sysoev.ru nxt_router_engine_conf_t *recf, nxt_queue_t *sockets); 16053Sigor@sysoev.ru 16153Sigor@sysoev.ru static nxt_int_t nxt_router_threads_create(nxt_task_t *task, nxt_runtime_t *rt, 16253Sigor@sysoev.ru nxt_router_temp_conf_t *tmcf); 16353Sigor@sysoev.ru static nxt_int_t nxt_router_thread_create(nxt_task_t *task, nxt_runtime_t *rt, 16453Sigor@sysoev.ru nxt_event_engine_t *engine); 165343Smax.romanov@nginx.com static void nxt_router_apps_sort(nxt_task_t *task, nxt_router_t *router, 166133Sigor@sysoev.ru nxt_router_temp_conf_t *tmcf); 16753Sigor@sysoev.ru 168315Sigor@sysoev.ru static void nxt_router_engines_post(nxt_router_t *router, 169315Sigor@sysoev.ru nxt_router_temp_conf_t *tmcf); 170315Sigor@sysoev.ru static void nxt_router_engine_post(nxt_event_engine_t *engine, 171315Sigor@sysoev.ru nxt_work_t *jobs); 17253Sigor@sysoev.ru 17353Sigor@sysoev.ru static void nxt_router_thread_start(void *data); 17453Sigor@sysoev.ru static void nxt_router_listen_socket_create(nxt_task_t *task, void *obj, 17553Sigor@sysoev.ru void *data); 17653Sigor@sysoev.ru static void nxt_router_listen_socket_update(nxt_task_t *task, void *obj, 17753Sigor@sysoev.ru void *data); 17853Sigor@sysoev.ru static void nxt_router_listen_socket_delete(nxt_task_t *task, void *obj, 17953Sigor@sysoev.ru void *data); 180313Sigor@sysoev.ru static void nxt_router_worker_thread_quit(nxt_task_t *task, void *obj, 181313Sigor@sysoev.ru void *data); 18253Sigor@sysoev.ru static void nxt_router_listen_socket_close(nxt_task_t *task, void *obj, 18353Sigor@sysoev.ru void *data); 18453Sigor@sysoev.ru static void nxt_router_thread_exit_handler(nxt_task_t *task, void *obj, 18553Sigor@sysoev.ru void *data); 186359Sigor@sysoev.ru static void nxt_router_listen_socket_release(nxt_task_t *task, 187359Sigor@sysoev.ru nxt_socket_conf_t *skcf); 18853Sigor@sysoev.ru static void nxt_router_conf_release(nxt_task_t *task, 18953Sigor@sysoev.ru nxt_socket_conf_joint_t *joint); 19053Sigor@sysoev.ru 191343Smax.romanov@nginx.com static void nxt_router_app_port_ready(nxt_task_t *task, 192343Smax.romanov@nginx.com nxt_port_recv_msg_t *msg, void *data); 193343Smax.romanov@nginx.com static void nxt_router_app_port_error(nxt_task_t *task, 194343Smax.romanov@nginx.com nxt_port_recv_msg_t *msg, void *data); 195343Smax.romanov@nginx.com 196343Smax.romanov@nginx.com static nxt_port_t * nxt_router_app_get_idle_port(nxt_app_t *app); 197343Smax.romanov@nginx.com static void nxt_router_app_port_release(nxt_task_t *task, nxt_port_t *port, 198343Smax.romanov@nginx.com uint32_t request_failed, uint32_t got_response); 199*427Smax.romanov@nginx.com static nxt_int_t nxt_router_app_port(nxt_task_t *task, nxt_app_t *app, 200*427Smax.romanov@nginx.com nxt_req_app_link_t *ra); 201141Smax.romanov@nginx.com 20253Sigor@sysoev.ru static void nxt_router_conn_init(nxt_task_t *task, void *obj, void *data); 20353Sigor@sysoev.ru static void nxt_router_conn_http_header_parse(nxt_task_t *task, void *obj, 20453Sigor@sysoev.ru void *data); 205359Sigor@sysoev.ru static nxt_sockaddr_t *nxt_router_local_addr(nxt_task_t *task, nxt_conn_t *c); 206206Smax.romanov@nginx.com static void nxt_router_conn_http_body_read(nxt_task_t *task, void *obj, 207206Smax.romanov@nginx.com void *data); 20888Smax.romanov@nginx.com static void nxt_router_process_http_request(nxt_task_t *task, 20988Smax.romanov@nginx.com nxt_conn_t *c, nxt_app_parse_ctx_t *ap); 210425Smax.romanov@nginx.com static void nxt_router_app_prepare_request(nxt_task_t *task, 211343Smax.romanov@nginx.com nxt_req_app_link_t *ra); 212216Sigor@sysoev.ru static nxt_int_t nxt_python_prepare_msg(nxt_task_t *task, nxt_app_request_t *r, 213216Sigor@sysoev.ru nxt_app_wmsg_t *wmsg); 214216Sigor@sysoev.ru static nxt_int_t nxt_php_prepare_msg(nxt_task_t *task, nxt_app_request_t *r, 215216Sigor@sysoev.ru nxt_app_wmsg_t *wmsg); 216216Sigor@sysoev.ru static nxt_int_t nxt_go_prepare_msg(nxt_task_t *task, nxt_app_request_t *r, 217216Sigor@sysoev.ru nxt_app_wmsg_t *wmsg); 21888Smax.romanov@nginx.com static void nxt_router_conn_ready(nxt_task_t *task, void *obj, void *data); 21953Sigor@sysoev.ru static void nxt_router_conn_close(nxt_task_t *task, void *obj, void *data); 22053Sigor@sysoev.ru static void nxt_router_conn_free(nxt_task_t *task, void *obj, void *data); 22153Sigor@sysoev.ru static void nxt_router_conn_error(nxt_task_t *task, void *obj, void *data); 22253Sigor@sysoev.ru static void nxt_router_conn_timeout(nxt_task_t *task, void *obj, void *data); 223318Smax.romanov@nginx.com static void nxt_router_app_timeout(nxt_task_t *task, void *obj, void *data); 22462Sigor@sysoev.ru static nxt_msec_t nxt_router_conn_timeout_value(nxt_conn_t *c, uintptr_t data); 22520Sigor@sysoev.ru 226141Smax.romanov@nginx.com static void nxt_router_gen_error(nxt_task_t *task, nxt_conn_t *c, int code, 227345Smax.romanov@nginx.com const char* str); 228141Smax.romanov@nginx.com 229119Smax.romanov@nginx.com static nxt_router_t *nxt_router; 23020Sigor@sysoev.ru 231216Sigor@sysoev.ru 232216Sigor@sysoev.ru static nxt_app_prepare_msg_t nxt_app_prepare_msg[] = { 233216Sigor@sysoev.ru nxt_python_prepare_msg, 234216Sigor@sysoev.ru nxt_php_prepare_msg, 235216Sigor@sysoev.ru nxt_go_prepare_msg, 236216Sigor@sysoev.ru }; 237216Sigor@sysoev.ru 238216Sigor@sysoev.ru 23920Sigor@sysoev.ru nxt_int_t 240141Smax.romanov@nginx.com nxt_router_start(nxt_task_t *task, void *data) 24120Sigor@sysoev.ru { 242141Smax.romanov@nginx.com nxt_int_t ret; 243141Smax.romanov@nginx.com nxt_router_t *router; 244141Smax.romanov@nginx.com nxt_runtime_t *rt; 245141Smax.romanov@nginx.com 246141Smax.romanov@nginx.com rt = task->thread->runtime; 24753Sigor@sysoev.ru 24888Smax.romanov@nginx.com ret = nxt_app_http_init(task, rt); 24988Smax.romanov@nginx.com if (nxt_slow_path(ret != NXT_OK)) { 25088Smax.romanov@nginx.com return ret; 25188Smax.romanov@nginx.com } 25288Smax.romanov@nginx.com 25353Sigor@sysoev.ru router = nxt_zalloc(sizeof(nxt_router_t)); 25453Sigor@sysoev.ru if (nxt_slow_path(router == NULL)) { 25553Sigor@sysoev.ru return NXT_ERROR; 25653Sigor@sysoev.ru } 25753Sigor@sysoev.ru 25853Sigor@sysoev.ru nxt_queue_init(&router->engines); 25953Sigor@sysoev.ru nxt_queue_init(&router->sockets); 260133Sigor@sysoev.ru nxt_queue_init(&router->apps); 26153Sigor@sysoev.ru 262119Smax.romanov@nginx.com nxt_router = router; 263119Smax.romanov@nginx.com 264115Sigor@sysoev.ru return NXT_OK; 265115Sigor@sysoev.ru } 266115Sigor@sysoev.ru 267115Sigor@sysoev.ru 268343Smax.romanov@nginx.com static void 269343Smax.romanov@nginx.com nxt_router_start_worker_handler(nxt_task_t *task, nxt_port_t *port, void *data) 270167Smax.romanov@nginx.com { 271343Smax.romanov@nginx.com size_t size; 272343Smax.romanov@nginx.com uint32_t stream; 273343Smax.romanov@nginx.com nxt_app_t *app; 274343Smax.romanov@nginx.com nxt_buf_t *b; 275343Smax.romanov@nginx.com nxt_port_t *main_port; 276343Smax.romanov@nginx.com nxt_runtime_t *rt; 277343Smax.romanov@nginx.com 278343Smax.romanov@nginx.com app = data; 279167Smax.romanov@nginx.com 280167Smax.romanov@nginx.com rt = task->thread->runtime; 281240Sigor@sysoev.ru main_port = rt->port_by_type[NXT_PROCESS_MAIN]; 282167Smax.romanov@nginx.com 283343Smax.romanov@nginx.com nxt_debug(task, "app '%V' %p start worker", &app->name, app); 284343Smax.romanov@nginx.com 285343Smax.romanov@nginx.com size = app->name.length + 1 + app->conf.length; 286343Smax.romanov@nginx.com 287343Smax.romanov@nginx.com b = nxt_buf_mem_ts_alloc(task, task->thread->engine->mem_pool, size); 288343Smax.romanov@nginx.com 289343Smax.romanov@nginx.com if (nxt_slow_path(b == NULL)) { 290343Smax.romanov@nginx.com goto failed; 291167Smax.romanov@nginx.com } 292167Smax.romanov@nginx.com 293343Smax.romanov@nginx.com nxt_buf_cpystr(b, &app->name); 294343Smax.romanov@nginx.com *b->mem.free++ = '\0'; 295343Smax.romanov@nginx.com nxt_buf_cpystr(b, &app->conf); 296343Smax.romanov@nginx.com 297343Smax.romanov@nginx.com stream = nxt_port_rpc_register_handler(task, port, 298343Smax.romanov@nginx.com nxt_router_app_port_ready, 299343Smax.romanov@nginx.com nxt_router_app_port_error, 300343Smax.romanov@nginx.com -1, app); 301343Smax.romanov@nginx.com 302343Smax.romanov@nginx.com if (nxt_slow_path(stream == 0)) { 303343Smax.romanov@nginx.com nxt_mp_release(b->data, b); 304343Smax.romanov@nginx.com 305343Smax.romanov@nginx.com goto failed; 306343Smax.romanov@nginx.com } 307343Smax.romanov@nginx.com 308343Smax.romanov@nginx.com nxt_port_socket_write(task, main_port, NXT_PORT_MSG_START_WORKER, -1, 309343Smax.romanov@nginx.com stream, port->id, b); 310343Smax.romanov@nginx.com 311343Smax.romanov@nginx.com return; 312343Smax.romanov@nginx.com 313343Smax.romanov@nginx.com failed: 314343Smax.romanov@nginx.com 315343Smax.romanov@nginx.com nxt_thread_mutex_lock(&app->mutex); 316343Smax.romanov@nginx.com 317343Smax.romanov@nginx.com app->pending_workers--; 318343Smax.romanov@nginx.com 319343Smax.romanov@nginx.com nxt_thread_mutex_unlock(&app->mutex); 320343Smax.romanov@nginx.com 321343Smax.romanov@nginx.com nxt_router_app_use(task, app, -1); 322167Smax.romanov@nginx.com } 323167Smax.romanov@nginx.com 324167Smax.romanov@nginx.com 325343Smax.romanov@nginx.com static nxt_int_t 326343Smax.romanov@nginx.com nxt_router_start_worker(nxt_task_t *task, nxt_app_t *app) 327141Smax.romanov@nginx.com { 328343Smax.romanov@nginx.com nxt_int_t res; 329343Smax.romanov@nginx.com nxt_port_t *router_port; 330343Smax.romanov@nginx.com nxt_runtime_t *rt; 331343Smax.romanov@nginx.com 332343Smax.romanov@nginx.com rt = task->thread->runtime; 333343Smax.romanov@nginx.com router_port = rt->port_by_type[NXT_PROCESS_ROUTER]; 334343Smax.romanov@nginx.com 335343Smax.romanov@nginx.com nxt_router_app_use(task, app, 1); 336343Smax.romanov@nginx.com 337343Smax.romanov@nginx.com res = nxt_port_post(task, router_port, nxt_router_start_worker_handler, 338343Smax.romanov@nginx.com app); 339343Smax.romanov@nginx.com 340343Smax.romanov@nginx.com if (res == NXT_OK) { 341343Smax.romanov@nginx.com return res; 342318Smax.romanov@nginx.com } 343318Smax.romanov@nginx.com 344343Smax.romanov@nginx.com nxt_thread_mutex_lock(&app->mutex); 345343Smax.romanov@nginx.com 346343Smax.romanov@nginx.com app->pending_workers--; 347343Smax.romanov@nginx.com 348343Smax.romanov@nginx.com nxt_thread_mutex_unlock(&app->mutex); 349343Smax.romanov@nginx.com 350343Smax.romanov@nginx.com nxt_router_app_use(task, app, -1); 351343Smax.romanov@nginx.com 352343Smax.romanov@nginx.com return NXT_ERROR; 353318Smax.romanov@nginx.com } 354318Smax.romanov@nginx.com 355318Smax.romanov@nginx.com 356351Smax.romanov@nginx.com nxt_inline void 357351Smax.romanov@nginx.com nxt_router_ra_init(nxt_task_t *task, nxt_req_app_link_t *ra, 358351Smax.romanov@nginx.com nxt_req_conn_link_t *rc) 359167Smax.romanov@nginx.com { 360318Smax.romanov@nginx.com nxt_event_engine_t *engine; 361351Smax.romanov@nginx.com 362318Smax.romanov@nginx.com engine = task->thread->engine; 363167Smax.romanov@nginx.com 364167Smax.romanov@nginx.com nxt_memzero(ra, sizeof(nxt_req_app_link_t)); 365167Smax.romanov@nginx.com 366318Smax.romanov@nginx.com ra->stream = rc->stream; 367425Smax.romanov@nginx.com ra->use_count = 1; 368167Smax.romanov@nginx.com ra->rc = rc; 369318Smax.romanov@nginx.com rc->ra = ra; 370318Smax.romanov@nginx.com ra->reply_port = engine->port; 371351Smax.romanov@nginx.com ra->ap = rc->ap; 372167Smax.romanov@nginx.com 373167Smax.romanov@nginx.com ra->work.handler = NULL; 374318Smax.romanov@nginx.com ra->work.task = &engine->task; 375167Smax.romanov@nginx.com ra->work.obj = ra; 376318Smax.romanov@nginx.com ra->work.data = engine; 377351Smax.romanov@nginx.com } 378351Smax.romanov@nginx.com 379351Smax.romanov@nginx.com 380351Smax.romanov@nginx.com nxt_inline nxt_req_app_link_t * 381351Smax.romanov@nginx.com nxt_router_ra_create(nxt_task_t *task, nxt_req_app_link_t *ra_src) 382351Smax.romanov@nginx.com { 383351Smax.romanov@nginx.com nxt_mp_t *mp; 384351Smax.romanov@nginx.com nxt_req_app_link_t *ra; 385351Smax.romanov@nginx.com 386425Smax.romanov@nginx.com if (ra_src->mem_pool != NULL) { 387425Smax.romanov@nginx.com return ra_src; 388425Smax.romanov@nginx.com } 389425Smax.romanov@nginx.com 390351Smax.romanov@nginx.com mp = ra_src->ap->mem_pool; 391351Smax.romanov@nginx.com 392351Smax.romanov@nginx.com ra = nxt_mp_retain(mp, sizeof(nxt_req_app_link_t)); 393351Smax.romanov@nginx.com 394351Smax.romanov@nginx.com if (nxt_slow_path(ra == NULL)) { 395351Smax.romanov@nginx.com 396351Smax.romanov@nginx.com ra_src->rc->ra = NULL; 397351Smax.romanov@nginx.com ra_src->rc = NULL; 398351Smax.romanov@nginx.com 399351Smax.romanov@nginx.com return NULL; 400351Smax.romanov@nginx.com } 401351Smax.romanov@nginx.com 402351Smax.romanov@nginx.com nxt_router_ra_init(task, ra, ra_src->rc); 403351Smax.romanov@nginx.com 404351Smax.romanov@nginx.com ra->mem_pool = mp; 405167Smax.romanov@nginx.com 406167Smax.romanov@nginx.com return ra; 407167Smax.romanov@nginx.com } 408167Smax.romanov@nginx.com 409167Smax.romanov@nginx.com 410423Smax.romanov@nginx.com nxt_inline nxt_bool_t 411423Smax.romanov@nginx.com nxt_router_msg_cancel(nxt_task_t *task, nxt_msg_info_t *msg_info, 412423Smax.romanov@nginx.com uint32_t stream) 413423Smax.romanov@nginx.com { 414423Smax.romanov@nginx.com nxt_buf_t *b, *next; 415423Smax.romanov@nginx.com nxt_bool_t cancelled; 416423Smax.romanov@nginx.com 417423Smax.romanov@nginx.com if (msg_info->buf == NULL) { 418423Smax.romanov@nginx.com return 0; 419423Smax.romanov@nginx.com } 420423Smax.romanov@nginx.com 421423Smax.romanov@nginx.com cancelled = nxt_port_mmap_tracking_cancel(task, &msg_info->tracking, 422423Smax.romanov@nginx.com stream); 423423Smax.romanov@nginx.com 424423Smax.romanov@nginx.com if (cancelled) { 425423Smax.romanov@nginx.com nxt_debug(task, "stream #%uD: cancelled by router", stream); 426423Smax.romanov@nginx.com } 427423Smax.romanov@nginx.com 428423Smax.romanov@nginx.com for (b = msg_info->buf; b != NULL; b = next) { 429423Smax.romanov@nginx.com next = b->next; 430423Smax.romanov@nginx.com 431423Smax.romanov@nginx.com b->completion_handler = msg_info->completion_handler; 432423Smax.romanov@nginx.com 433423Smax.romanov@nginx.com if (b->is_port_mmap_sent) { 434423Smax.romanov@nginx.com b->is_port_mmap_sent = cancelled == 0; 435423Smax.romanov@nginx.com b->completion_handler(task, b, b->parent); 436423Smax.romanov@nginx.com } 437423Smax.romanov@nginx.com } 438423Smax.romanov@nginx.com 439423Smax.romanov@nginx.com msg_info->buf = NULL; 440423Smax.romanov@nginx.com 441423Smax.romanov@nginx.com return cancelled; 442423Smax.romanov@nginx.com } 443423Smax.romanov@nginx.com 444423Smax.romanov@nginx.com 445167Smax.romanov@nginx.com static void 446425Smax.romanov@nginx.com nxt_router_ra_update_peer(nxt_task_t *task, nxt_req_app_link_t *ra); 447425Smax.romanov@nginx.com 448425Smax.romanov@nginx.com 449425Smax.romanov@nginx.com static void 450425Smax.romanov@nginx.com nxt_router_ra_update_peer_handler(nxt_task_t *task, void *obj, void *data) 451167Smax.romanov@nginx.com { 452425Smax.romanov@nginx.com nxt_req_app_link_t *ra; 453425Smax.romanov@nginx.com 454425Smax.romanov@nginx.com ra = obj; 455425Smax.romanov@nginx.com 456425Smax.romanov@nginx.com nxt_router_ra_update_peer(task, ra); 457425Smax.romanov@nginx.com 458425Smax.romanov@nginx.com nxt_router_ra_use(task, ra, -1); 459425Smax.romanov@nginx.com } 460425Smax.romanov@nginx.com 461425Smax.romanov@nginx.com 462425Smax.romanov@nginx.com static void 463425Smax.romanov@nginx.com nxt_router_ra_update_peer(nxt_task_t *task, nxt_req_app_link_t *ra) 464425Smax.romanov@nginx.com { 465343Smax.romanov@nginx.com nxt_event_engine_t *engine; 466343Smax.romanov@nginx.com nxt_req_conn_link_t *rc; 467318Smax.romanov@nginx.com 468425Smax.romanov@nginx.com engine = ra->work.data; 469318Smax.romanov@nginx.com 470343Smax.romanov@nginx.com if (task->thread->engine != engine) { 471425Smax.romanov@nginx.com nxt_router_ra_inc_use(ra); 472425Smax.romanov@nginx.com 473425Smax.romanov@nginx.com ra->work.handler = nxt_router_ra_update_peer_handler; 474318Smax.romanov@nginx.com ra->work.task = &engine->task; 475318Smax.romanov@nginx.com ra->work.next = NULL; 476318Smax.romanov@nginx.com 477425Smax.romanov@nginx.com nxt_debug(task, "ra stream #%uD post update peer to %p", 478318Smax.romanov@nginx.com ra->stream, engine); 479318Smax.romanov@nginx.com 480318Smax.romanov@nginx.com nxt_event_engine_post(engine, &ra->work); 481318Smax.romanov@nginx.com 482318Smax.romanov@nginx.com return; 483318Smax.romanov@nginx.com } 484318Smax.romanov@nginx.com 485425Smax.romanov@nginx.com nxt_debug(task, "ra stream #%uD update peer", ra->stream); 486425Smax.romanov@nginx.com 487425Smax.romanov@nginx.com rc = ra->rc; 488425Smax.romanov@nginx.com 489425Smax.romanov@nginx.com if (rc != NULL && ra->app_port != NULL) { 490425Smax.romanov@nginx.com nxt_port_rpc_ex_set_peer(task, engine->port, rc, ra->app_port->pid); 491425Smax.romanov@nginx.com } 492425Smax.romanov@nginx.com 493425Smax.romanov@nginx.com nxt_router_ra_use(task, ra, -1); 494425Smax.romanov@nginx.com } 495425Smax.romanov@nginx.com 496425Smax.romanov@nginx.com 497425Smax.romanov@nginx.com static void 498425Smax.romanov@nginx.com nxt_router_ra_release(nxt_task_t *task, nxt_req_app_link_t *ra) 499425Smax.romanov@nginx.com { 500425Smax.romanov@nginx.com nxt_conn_t *c; 501425Smax.romanov@nginx.com nxt_req_conn_link_t *rc; 502425Smax.romanov@nginx.com 503425Smax.romanov@nginx.com nxt_assert(task->thread->engine == ra->work.data); 504425Smax.romanov@nginx.com nxt_assert(ra->use_count == 0); 505425Smax.romanov@nginx.com 506343Smax.romanov@nginx.com nxt_debug(task, "ra stream #%uD release", ra->stream); 507343Smax.romanov@nginx.com 508343Smax.romanov@nginx.com rc = ra->rc; 509343Smax.romanov@nginx.com 510343Smax.romanov@nginx.com if (rc != NULL) { 511425Smax.romanov@nginx.com c = rc->conn; 512343Smax.romanov@nginx.com 513423Smax.romanov@nginx.com if (nxt_slow_path(ra->err_code != 0)) { 514425Smax.romanov@nginx.com nxt_router_gen_error(task, c, ra->err_code, ra->err_str); 515423Smax.romanov@nginx.com 516423Smax.romanov@nginx.com } else { 517423Smax.romanov@nginx.com rc->app_port = ra->app_port; 518423Smax.romanov@nginx.com rc->msg_info = ra->msg_info; 519423Smax.romanov@nginx.com 520425Smax.romanov@nginx.com if (rc->app->timeout != 0) { 521425Smax.romanov@nginx.com c->read_timer.handler = nxt_router_app_timeout; 522425Smax.romanov@nginx.com nxt_timer_add(task->thread->engine, &c->read_timer, 523425Smax.romanov@nginx.com rc->app->timeout); 524425Smax.romanov@nginx.com } 525425Smax.romanov@nginx.com 526423Smax.romanov@nginx.com ra->app_port = NULL; 527423Smax.romanov@nginx.com ra->msg_info.buf = NULL; 528423Smax.romanov@nginx.com } 529343Smax.romanov@nginx.com 530343Smax.romanov@nginx.com rc->ra = NULL; 531343Smax.romanov@nginx.com ra->rc = NULL; 532343Smax.romanov@nginx.com } 533343Smax.romanov@nginx.com 534343Smax.romanov@nginx.com if (ra->app_port != NULL) { 535343Smax.romanov@nginx.com nxt_router_app_port_release(task, ra->app_port, 0, 1); 536343Smax.romanov@nginx.com 537343Smax.romanov@nginx.com ra->app_port = NULL; 538167Smax.romanov@nginx.com } 539167Smax.romanov@nginx.com 540423Smax.romanov@nginx.com nxt_router_msg_cancel(task, &ra->msg_info, ra->stream); 541423Smax.romanov@nginx.com 542351Smax.romanov@nginx.com if (ra->mem_pool != NULL) { 543351Smax.romanov@nginx.com nxt_mp_release(ra->mem_pool, ra); 544351Smax.romanov@nginx.com } 545167Smax.romanov@nginx.com } 546167Smax.romanov@nginx.com 547167Smax.romanov@nginx.com 548425Smax.romanov@nginx.com static void 549425Smax.romanov@nginx.com nxt_router_ra_release_handler(nxt_task_t *task, void *obj, void *data) 550425Smax.romanov@nginx.com { 551425Smax.romanov@nginx.com nxt_req_app_link_t *ra; 552425Smax.romanov@nginx.com 553425Smax.romanov@nginx.com ra = obj; 554425Smax.romanov@nginx.com 555425Smax.romanov@nginx.com nxt_assert(ra->work.data == data); 556425Smax.romanov@nginx.com 557425Smax.romanov@nginx.com nxt_atomic_fetch_add(&ra->use_count, -1); 558425Smax.romanov@nginx.com 559425Smax.romanov@nginx.com nxt_router_ra_release(task, ra); 560425Smax.romanov@nginx.com } 561425Smax.romanov@nginx.com 562425Smax.romanov@nginx.com 563425Smax.romanov@nginx.com static void 564425Smax.romanov@nginx.com nxt_router_ra_use(nxt_task_t *task, nxt_req_app_link_t *ra, int i) 565425Smax.romanov@nginx.com { 566425Smax.romanov@nginx.com int c; 567425Smax.romanov@nginx.com nxt_event_engine_t *engine; 568425Smax.romanov@nginx.com 569425Smax.romanov@nginx.com c = nxt_atomic_fetch_add(&ra->use_count, i); 570425Smax.romanov@nginx.com 571425Smax.romanov@nginx.com if (i < 0 && c == -i) { 572425Smax.romanov@nginx.com engine = ra->work.data; 573425Smax.romanov@nginx.com 574425Smax.romanov@nginx.com if (task->thread->engine == engine) { 575425Smax.romanov@nginx.com nxt_router_ra_release(task, ra); 576425Smax.romanov@nginx.com 577425Smax.romanov@nginx.com return; 578425Smax.romanov@nginx.com } 579425Smax.romanov@nginx.com 580425Smax.romanov@nginx.com nxt_router_ra_inc_use(ra); 581425Smax.romanov@nginx.com 582425Smax.romanov@nginx.com ra->work.handler = nxt_router_ra_release_handler; 583425Smax.romanov@nginx.com ra->work.task = &engine->task; 584425Smax.romanov@nginx.com ra->work.next = NULL; 585425Smax.romanov@nginx.com 586425Smax.romanov@nginx.com nxt_debug(task, "ra stream #%uD post release to %p", 587425Smax.romanov@nginx.com ra->stream, engine); 588425Smax.romanov@nginx.com 589425Smax.romanov@nginx.com nxt_event_engine_post(engine, &ra->work); 590425Smax.romanov@nginx.com } 591425Smax.romanov@nginx.com } 592425Smax.romanov@nginx.com 593425Smax.romanov@nginx.com 594423Smax.romanov@nginx.com nxt_inline void 595423Smax.romanov@nginx.com nxt_router_ra_error(nxt_req_app_link_t *ra, int code, const char* str) 596345Smax.romanov@nginx.com { 597423Smax.romanov@nginx.com ra->app_port = NULL; 598423Smax.romanov@nginx.com ra->err_code = code; 599423Smax.romanov@nginx.com ra->err_str = str; 600345Smax.romanov@nginx.com } 601345Smax.romanov@nginx.com 602345Smax.romanov@nginx.com 603*427Smax.romanov@nginx.com nxt_inline void 604*427Smax.romanov@nginx.com nxt_router_ra_pending(nxt_task_t *task, nxt_app_t *app, nxt_req_app_link_t *ra) 605*427Smax.romanov@nginx.com { 606*427Smax.romanov@nginx.com nxt_queue_insert_tail(&ra->app_port->pending_requests, 607*427Smax.romanov@nginx.com &ra->link_port_pending); 608*427Smax.romanov@nginx.com nxt_queue_insert_tail(&app->pending, &ra->link_app_pending); 609*427Smax.romanov@nginx.com 610*427Smax.romanov@nginx.com nxt_router_ra_inc_use(ra); 611*427Smax.romanov@nginx.com 612*427Smax.romanov@nginx.com ra->res_time = nxt_thread_monotonic_time(task->thread) + app->res_timeout; 613*427Smax.romanov@nginx.com 614*427Smax.romanov@nginx.com nxt_debug(task, "ra stream #%uD enqueue to pending_requests", ra->stream); 615*427Smax.romanov@nginx.com } 616*427Smax.romanov@nginx.com 617*427Smax.romanov@nginx.com 618425Smax.romanov@nginx.com nxt_inline nxt_bool_t 619425Smax.romanov@nginx.com nxt_queue_chk_remove(nxt_queue_link_t *lnk) 620425Smax.romanov@nginx.com { 621425Smax.romanov@nginx.com if (lnk->next != NULL) { 622425Smax.romanov@nginx.com nxt_queue_remove(lnk); 623425Smax.romanov@nginx.com 624425Smax.romanov@nginx.com lnk->next = NULL; 625425Smax.romanov@nginx.com 626425Smax.romanov@nginx.com return 1; 627425Smax.romanov@nginx.com } 628425Smax.romanov@nginx.com 629425Smax.romanov@nginx.com return 0; 630425Smax.romanov@nginx.com } 631425Smax.romanov@nginx.com 632425Smax.romanov@nginx.com 633343Smax.romanov@nginx.com nxt_inline void 634343Smax.romanov@nginx.com nxt_router_rc_unlink(nxt_task_t *task, nxt_req_conn_link_t *rc) 635343Smax.romanov@nginx.com { 636425Smax.romanov@nginx.com int ra_use_delta; 637343Smax.romanov@nginx.com nxt_req_app_link_t *ra; 638343Smax.romanov@nginx.com 639343Smax.romanov@nginx.com if (rc->app_port != NULL) { 640343Smax.romanov@nginx.com nxt_router_app_port_release(task, rc->app_port, 0, 1); 641343Smax.romanov@nginx.com 642343Smax.romanov@nginx.com rc->app_port = NULL; 643343Smax.romanov@nginx.com } 644343Smax.romanov@nginx.com 645423Smax.romanov@nginx.com nxt_router_msg_cancel(task, &rc->msg_info, rc->stream); 646423Smax.romanov@nginx.com 647343Smax.romanov@nginx.com ra = rc->ra; 648343Smax.romanov@nginx.com 649343Smax.romanov@nginx.com if (ra != NULL) { 650343Smax.romanov@nginx.com rc->ra = NULL; 651343Smax.romanov@nginx.com ra->rc = NULL; 652343Smax.romanov@nginx.com 653425Smax.romanov@nginx.com ra_use_delta = 0; 654425Smax.romanov@nginx.com 655343Smax.romanov@nginx.com nxt_thread_mutex_lock(&rc->app->mutex); 656343Smax.romanov@nginx.com 657425Smax.romanov@nginx.com if (ra->link_app_requests.next == NULL 658*427Smax.romanov@nginx.com && ra->link_port_pending.next == NULL 659*427Smax.romanov@nginx.com && ra->link_app_pending.next == NULL) 660425Smax.romanov@nginx.com { 661425Smax.romanov@nginx.com ra = NULL; 662343Smax.romanov@nginx.com 663343Smax.romanov@nginx.com } else { 664425Smax.romanov@nginx.com ra_use_delta -= nxt_queue_chk_remove(&ra->link_app_requests); 665425Smax.romanov@nginx.com ra_use_delta -= nxt_queue_chk_remove(&ra->link_port_pending); 666*427Smax.romanov@nginx.com nxt_queue_chk_remove(&ra->link_app_pending); 667343Smax.romanov@nginx.com } 668343Smax.romanov@nginx.com 669343Smax.romanov@nginx.com nxt_thread_mutex_unlock(&rc->app->mutex); 670425Smax.romanov@nginx.com 671425Smax.romanov@nginx.com if (ra != NULL) { 672425Smax.romanov@nginx.com nxt_router_ra_use(task, ra, ra_use_delta); 673425Smax.romanov@nginx.com } 674343Smax.romanov@nginx.com } 675343Smax.romanov@nginx.com 676343Smax.romanov@nginx.com if (rc->app != NULL) { 677343Smax.romanov@nginx.com nxt_router_app_use(task, rc->app, -1); 678343Smax.romanov@nginx.com 679343Smax.romanov@nginx.com rc->app = NULL; 680343Smax.romanov@nginx.com } 681343Smax.romanov@nginx.com 682346Smax.romanov@nginx.com if (rc->ap != NULL) { 683346Smax.romanov@nginx.com nxt_app_http_req_done(task, rc->ap); 684346Smax.romanov@nginx.com 685346Smax.romanov@nginx.com rc->ap = NULL; 686346Smax.romanov@nginx.com } 687346Smax.romanov@nginx.com 688343Smax.romanov@nginx.com nxt_queue_remove(&rc->link); 689343Smax.romanov@nginx.com 690343Smax.romanov@nginx.com rc->conn = NULL; 691343Smax.romanov@nginx.com } 692343Smax.romanov@nginx.com 693343Smax.romanov@nginx.com 694141Smax.romanov@nginx.com void 695141Smax.romanov@nginx.com nxt_router_new_port_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg) 696141Smax.romanov@nginx.com { 697141Smax.romanov@nginx.com nxt_port_new_port_handler(task, msg); 698141Smax.romanov@nginx.com 699192Smax.romanov@nginx.com if (msg->port_msg.stream == 0) { 700141Smax.romanov@nginx.com return; 701141Smax.romanov@nginx.com } 702141Smax.romanov@nginx.com 703426Smax.romanov@nginx.com if (msg->u.new_port == NULL 704426Smax.romanov@nginx.com || msg->u.new_port->type != NXT_PROCESS_WORKER) 705347Smax.romanov@nginx.com { 706192Smax.romanov@nginx.com msg->port_msg.type = _NXT_PORT_MSG_RPC_ERROR; 707141Smax.romanov@nginx.com } 708192Smax.romanov@nginx.com 709192Smax.romanov@nginx.com nxt_port_rpc_handler(task, msg); 710141Smax.romanov@nginx.com } 711141Smax.romanov@nginx.com 712141Smax.romanov@nginx.com 713139Sigor@sysoev.ru void 714139Sigor@sysoev.ru nxt_router_conf_data_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg) 715115Sigor@sysoev.ru { 716198Sigor@sysoev.ru nxt_int_t ret; 717139Sigor@sysoev.ru nxt_buf_t *b; 718139Sigor@sysoev.ru nxt_router_temp_conf_t *tmcf; 719139Sigor@sysoev.ru 720139Sigor@sysoev.ru tmcf = nxt_router_temp_conf(task); 721139Sigor@sysoev.ru if (nxt_slow_path(tmcf == NULL)) { 722139Sigor@sysoev.ru return; 72353Sigor@sysoev.ru } 72453Sigor@sysoev.ru 725423Smax.romanov@nginx.com nxt_debug(task, "nxt_router_conf_data_handler(%d): %*s", 726423Smax.romanov@nginx.com nxt_buf_used_size(msg->buf), 727423Smax.romanov@nginx.com nxt_buf_used_size(msg->buf), msg->buf->mem.pos); 728423Smax.romanov@nginx.com 729352Smax.romanov@nginx.com b = nxt_buf_chk_make_plain(tmcf->conf->mem_pool, msg->buf, msg->size); 730352Smax.romanov@nginx.com 731352Smax.romanov@nginx.com nxt_assert(b != NULL); 732352Smax.romanov@nginx.com 733139Sigor@sysoev.ru tmcf->conf->router = nxt_router; 734139Sigor@sysoev.ru tmcf->stream = msg->port_msg.stream; 735139Sigor@sysoev.ru tmcf->port = nxt_runtime_port_find(task->thread->runtime, 736198Sigor@sysoev.ru msg->port_msg.pid, 737198Sigor@sysoev.ru msg->port_msg.reply_port); 738198Sigor@sysoev.ru 739198Sigor@sysoev.ru ret = nxt_router_conf_create(task, tmcf, b->mem.pos, b->mem.free); 740198Sigor@sysoev.ru 741198Sigor@sysoev.ru if (nxt_fast_path(ret == NXT_OK)) { 742198Sigor@sysoev.ru nxt_router_conf_apply(task, tmcf, NULL); 743198Sigor@sysoev.ru 744198Sigor@sysoev.ru } else { 745198Sigor@sysoev.ru nxt_router_conf_error(task, tmcf); 746139Sigor@sysoev.ru } 74753Sigor@sysoev.ru } 74853Sigor@sysoev.ru 74953Sigor@sysoev.ru 750347Smax.romanov@nginx.com static void 751347Smax.romanov@nginx.com nxt_router_worker_remove_pid(nxt_task_t *task, nxt_port_t *port, void *data) 752347Smax.romanov@nginx.com { 753347Smax.romanov@nginx.com union { 754347Smax.romanov@nginx.com nxt_pid_t removed_pid; 755347Smax.romanov@nginx.com void *data; 756347Smax.romanov@nginx.com } u; 757347Smax.romanov@nginx.com 758347Smax.romanov@nginx.com u.data = data; 759347Smax.romanov@nginx.com 760347Smax.romanov@nginx.com nxt_port_rpc_remove_peer(task, port, u.removed_pid); 761347Smax.romanov@nginx.com } 762347Smax.romanov@nginx.com 763347Smax.romanov@nginx.com 764192Smax.romanov@nginx.com void 765192Smax.romanov@nginx.com nxt_router_remove_pid_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg) 766192Smax.romanov@nginx.com { 767347Smax.romanov@nginx.com nxt_event_engine_t *engine; 768318Smax.romanov@nginx.com 769192Smax.romanov@nginx.com nxt_port_remove_pid_handler(task, msg); 770192Smax.romanov@nginx.com 771192Smax.romanov@nginx.com if (msg->port_msg.stream == 0) { 772192Smax.romanov@nginx.com return; 773192Smax.romanov@nginx.com } 774192Smax.romanov@nginx.com 775318Smax.romanov@nginx.com nxt_queue_each(engine, &nxt_router->engines, nxt_event_engine_t, link0) 776318Smax.romanov@nginx.com { 777347Smax.romanov@nginx.com nxt_port_post(task, engine->port, nxt_router_worker_remove_pid, 778347Smax.romanov@nginx.com msg->u.data); 779318Smax.romanov@nginx.com } 780318Smax.romanov@nginx.com nxt_queue_loop; 781318Smax.romanov@nginx.com 782192Smax.romanov@nginx.com msg->port_msg.type = _NXT_PORT_MSG_RPC_ERROR; 783192Smax.romanov@nginx.com 784192Smax.romanov@nginx.com nxt_port_rpc_handler(task, msg); 785192Smax.romanov@nginx.com } 786192Smax.romanov@nginx.com 787192Smax.romanov@nginx.com 78853Sigor@sysoev.ru static nxt_router_temp_conf_t * 789139Sigor@sysoev.ru nxt_router_temp_conf(nxt_task_t *task) 79053Sigor@sysoev.ru { 79165Sigor@sysoev.ru nxt_mp_t *mp, *tmp; 79253Sigor@sysoev.ru nxt_router_conf_t *rtcf; 79353Sigor@sysoev.ru nxt_router_temp_conf_t *tmcf; 79453Sigor@sysoev.ru 79565Sigor@sysoev.ru mp = nxt_mp_create(1024, 128, 256, 32); 79653Sigor@sysoev.ru if (nxt_slow_path(mp == NULL)) { 79753Sigor@sysoev.ru return NULL; 79853