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> 10774Svbart@nginx.com #if (NXT_TLS) 11774Svbart@nginx.com #include <nxt_cert.h> 12774Svbart@nginx.com #endif 13431Sigor@sysoev.ru #include <nxt_http.h> 14743Smax.romanov@nginx.com #include <nxt_port_memory_int.h> 15743Smax.romanov@nginx.com #include <nxt_unit_request.h> 16743Smax.romanov@nginx.com #include <nxt_unit_response.h> 171131Smax.romanov@nginx.com #include <nxt_router_request.h> 181555Smax.romanov@nginx.com #include <nxt_app_queue.h> 191555Smax.romanov@nginx.com #include <nxt_port_queue.h> 2020Sigor@sysoev.ru 21115Sigor@sysoev.ru typedef struct { 22318Smax.romanov@nginx.com nxt_str_t type; 23507Smax.romanov@nginx.com uint32_t processes; 24507Smax.romanov@nginx.com uint32_t max_processes; 25507Smax.romanov@nginx.com uint32_t spare_processes; 26318Smax.romanov@nginx.com nxt_msec_t timeout; 27507Smax.romanov@nginx.com nxt_msec_t idle_timeout; 28318Smax.romanov@nginx.com uint32_t requests; 29318Smax.romanov@nginx.com nxt_conf_value_t *limits_value; 30507Smax.romanov@nginx.com nxt_conf_value_t *processes_value; 311473Svbart@nginx.com nxt_conf_value_t *targets_value; 32133Sigor@sysoev.ru } nxt_router_app_conf_t; 33133Sigor@sysoev.ru 34133Sigor@sysoev.ru 35133Sigor@sysoev.ru typedef struct { 36964Sigor@sysoev.ru nxt_str_t pass; 37964Sigor@sysoev.ru nxt_str_t application; 38115Sigor@sysoev.ru } nxt_router_listener_conf_t; 39115Sigor@sysoev.ru 40115Sigor@sysoev.ru 41774Svbart@nginx.com #if (NXT_TLS) 42774Svbart@nginx.com 43774Svbart@nginx.com typedef struct { 441885Sa.suvorov@f5.com nxt_str_t name; 451885Sa.suvorov@f5.com nxt_socket_conf_t *socket_conf; 461885Sa.suvorov@f5.com nxt_router_temp_conf_t *temp_conf; 471885Sa.suvorov@f5.com nxt_conf_value_t *conf_cmds; 481885Sa.suvorov@f5.com nxt_bool_t last; 49774Svbart@nginx.com 50774Svbart@nginx.com nxt_queue_link_t link; /* for nxt_socket_conf_t.tls */ 51774Svbart@nginx.com } nxt_router_tlssock_t; 52774Svbart@nginx.com 53774Svbart@nginx.com #endif 54774Svbart@nginx.com 55774Svbart@nginx.com 56198Sigor@sysoev.ru typedef struct { 571828Sa.suvorov@f5.com nxt_str_t *name; 58198Sigor@sysoev.ru nxt_socket_conf_t *socket_conf; 59198Sigor@sysoev.ru nxt_router_temp_conf_t *temp_conf; 601828Sa.suvorov@f5.com nxt_bool_t last; 61198Sigor@sysoev.ru } nxt_socket_rpc_t; 62198Sigor@sysoev.ru 63198Sigor@sysoev.ru 64507Smax.romanov@nginx.com typedef struct { 65507Smax.romanov@nginx.com nxt_app_t *app; 66507Smax.romanov@nginx.com nxt_router_temp_conf_t *temp_conf; 67507Smax.romanov@nginx.com } nxt_app_rpc_t; 68507Smax.romanov@nginx.com 69507Smax.romanov@nginx.com 701488St.nateldemoura@f5.com static nxt_int_t nxt_router_prefork(nxt_task_t *task, nxt_process_t *process, 711488St.nateldemoura@f5.com nxt_mp_t *mp); 721488St.nateldemoura@f5.com static nxt_int_t nxt_router_start(nxt_task_t *task, nxt_process_data_t *data); 73662Smax.romanov@nginx.com static void nxt_router_greet_controller(nxt_task_t *task, 74662Smax.romanov@nginx.com nxt_port_t *controller_port); 75662Smax.romanov@nginx.com 76507Smax.romanov@nginx.com static nxt_int_t nxt_router_start_app_process(nxt_task_t *task, nxt_app_t *app); 77425Smax.romanov@nginx.com 781552Smax.romanov@nginx.com static void nxt_router_new_port_handler(nxt_task_t *task, 791552Smax.romanov@nginx.com nxt_port_recv_msg_t *msg); 801552Smax.romanov@nginx.com static void nxt_router_conf_data_handler(nxt_task_t *task, 811552Smax.romanov@nginx.com nxt_port_recv_msg_t *msg); 821552Smax.romanov@nginx.com static void nxt_router_remove_pid_handler(nxt_task_t *task, 831552Smax.romanov@nginx.com nxt_port_recv_msg_t *msg); 841552Smax.romanov@nginx.com static void nxt_router_access_log_reopen_handler(nxt_task_t *task, 851552Smax.romanov@nginx.com nxt_port_recv_msg_t *msg); 861552Smax.romanov@nginx.com 87139Sigor@sysoev.ru static nxt_router_temp_conf_t *nxt_router_temp_conf(nxt_task_t *task); 88198Sigor@sysoev.ru static void nxt_router_conf_apply(nxt_task_t *task, void *obj, void *data); 89198Sigor@sysoev.ru static void nxt_router_conf_ready(nxt_task_t *task, 90139Sigor@sysoev.ru nxt_router_temp_conf_t *tmcf); 91139Sigor@sysoev.ru static void nxt_router_conf_error(nxt_task_t *task, 92139Sigor@sysoev.ru nxt_router_temp_conf_t *tmcf); 93139Sigor@sysoev.ru static void nxt_router_conf_send(nxt_task_t *task, 94193Smax.romanov@nginx.com nxt_router_temp_conf_t *tmcf, nxt_port_msg_type_t type); 9553Sigor@sysoev.ru 96115Sigor@sysoev.ru static nxt_int_t nxt_router_conf_create(nxt_task_t *task, 97115Sigor@sysoev.ru nxt_router_temp_conf_t *tmcf, u_char *start, u_char *end); 981183Svbart@nginx.com static nxt_int_t nxt_router_conf_process_static(nxt_task_t *task, 991183Svbart@nginx.com nxt_router_conf_t *rtcf, nxt_conf_value_t *conf); 1001563Svbart@nginx.com 101133Sigor@sysoev.ru static nxt_app_t *nxt_router_app_find(nxt_queue_t *queue, nxt_str_t *name); 1021563Svbart@nginx.com static nxt_int_t nxt_router_apps_hash_test(nxt_lvlhsh_query_t *lhq, void *data); 1031563Svbart@nginx.com static nxt_int_t nxt_router_apps_hash_add(nxt_router_conf_t *rtcf, 1041563Svbart@nginx.com nxt_app_t *app); 1051563Svbart@nginx.com static nxt_app_t *nxt_router_apps_hash_get(nxt_router_conf_t *rtcf, 1061563Svbart@nginx.com nxt_str_t *name); 1071563Svbart@nginx.com static void nxt_router_apps_hash_use(nxt_task_t *task, nxt_router_conf_t *rtcf, 1081563Svbart@nginx.com int i); 1091563Svbart@nginx.com 1101555Smax.romanov@nginx.com static nxt_int_t nxt_router_app_queue_init(nxt_task_t *task, 1111555Smax.romanov@nginx.com nxt_port_t *port); 1121555Smax.romanov@nginx.com static nxt_int_t nxt_router_port_queue_init(nxt_task_t *task, 1131555Smax.romanov@nginx.com nxt_port_t *port); 1141555Smax.romanov@nginx.com static nxt_int_t nxt_router_port_queue_map(nxt_task_t *task, 1151555Smax.romanov@nginx.com nxt_port_t *port, nxt_fd_t fd); 116198Sigor@sysoev.ru static void nxt_router_listen_socket_rpc_create(nxt_task_t *task, 117198Sigor@sysoev.ru nxt_router_temp_conf_t *tmcf, nxt_socket_conf_t *skcf); 118198Sigor@sysoev.ru static void nxt_router_listen_socket_ready(nxt_task_t *task, 119198Sigor@sysoev.ru nxt_port_recv_msg_t *msg, void *data); 120198Sigor@sysoev.ru static void nxt_router_listen_socket_error(nxt_task_t *task, 121198Sigor@sysoev.ru nxt_port_recv_msg_t *msg, void *data); 122774Svbart@nginx.com #if (NXT_TLS) 123774Svbart@nginx.com static void nxt_router_tls_rpc_handler(nxt_task_t *task, 124774Svbart@nginx.com nxt_port_recv_msg_t *msg, void *data); 1251828Sa.suvorov@f5.com static nxt_int_t nxt_router_conf_tls_insert(nxt_router_temp_conf_t *tmcf, 1261885Sa.suvorov@f5.com nxt_conf_value_t *value, nxt_socket_conf_t *skcf, 1271904Smax.romanov@nginx.com nxt_conf_value_t * conf_cmds, nxt_bool_t last); 128774Svbart@nginx.com #endif 129507Smax.romanov@nginx.com static void nxt_router_app_rpc_create(nxt_task_t *task, 130507Smax.romanov@nginx.com nxt_router_temp_conf_t *tmcf, nxt_app_t *app); 131507Smax.romanov@nginx.com static void nxt_router_app_prefork_ready(nxt_task_t *task, 132507Smax.romanov@nginx.com nxt_port_recv_msg_t *msg, void *data); 133507Smax.romanov@nginx.com static void nxt_router_app_prefork_error(nxt_task_t *task, 134507Smax.romanov@nginx.com nxt_port_recv_msg_t *msg, void *data); 135359Sigor@sysoev.ru static nxt_socket_conf_t *nxt_router_socket_conf(nxt_task_t *task, 136359Sigor@sysoev.ru nxt_router_temp_conf_t *tmcf, nxt_str_t *name); 137359Sigor@sysoev.ru static nxt_int_t nxt_router_listen_socket_find(nxt_router_temp_conf_t *tmcf, 138359Sigor@sysoev.ru nxt_socket_conf_t *nskcf, nxt_sockaddr_t *sa); 13953Sigor@sysoev.ru 14053Sigor@sysoev.ru static nxt_int_t nxt_router_engines_create(nxt_task_t *task, 14153Sigor@sysoev.ru nxt_router_t *router, nxt_router_temp_conf_t *tmcf, 14253Sigor@sysoev.ru const nxt_event_interface_t *interface); 143115Sigor@sysoev.ru static nxt_int_t nxt_router_engine_conf_create(nxt_router_temp_conf_t *tmcf, 144115Sigor@sysoev.ru nxt_router_engine_conf_t *recf); 145115Sigor@sysoev.ru static nxt_int_t nxt_router_engine_conf_update(nxt_router_temp_conf_t *tmcf, 146115Sigor@sysoev.ru nxt_router_engine_conf_t *recf); 147115Sigor@sysoev.ru static nxt_int_t nxt_router_engine_conf_delete(nxt_router_temp_conf_t *tmcf, 148115Sigor@sysoev.ru nxt_router_engine_conf_t *recf); 149154Sigor@sysoev.ru static nxt_int_t nxt_router_engine_joints_create(nxt_router_temp_conf_t *tmcf, 150154Sigor@sysoev.ru nxt_router_engine_conf_t *recf, nxt_queue_t *sockets, 151154Sigor@sysoev.ru nxt_work_handler_t handler); 152313Sigor@sysoev.ru static nxt_int_t nxt_router_engine_quit(nxt_router_temp_conf_t *tmcf, 153313Sigor@sysoev.ru nxt_router_engine_conf_t *recf); 154139Sigor@sysoev.ru static nxt_int_t nxt_router_engine_joints_delete(nxt_router_temp_conf_t *tmcf, 155139Sigor@sysoev.ru nxt_router_engine_conf_t *recf, nxt_queue_t *sockets); 15653Sigor@sysoev.ru 15753Sigor@sysoev.ru static nxt_int_t nxt_router_threads_create(nxt_task_t *task, nxt_runtime_t *rt, 15853Sigor@sysoev.ru nxt_router_temp_conf_t *tmcf); 15953Sigor@sysoev.ru static nxt_int_t nxt_router_thread_create(nxt_task_t *task, nxt_runtime_t *rt, 16053Sigor@sysoev.ru nxt_event_engine_t *engine); 161343Smax.romanov@nginx.com static void nxt_router_apps_sort(nxt_task_t *task, nxt_router_t *router, 162133Sigor@sysoev.ru nxt_router_temp_conf_t *tmcf); 16353Sigor@sysoev.ru 164315Sigor@sysoev.ru static void nxt_router_engines_post(nxt_router_t *router, 165315Sigor@sysoev.ru nxt_router_temp_conf_t *tmcf); 166315Sigor@sysoev.ru static void nxt_router_engine_post(nxt_event_engine_t *engine, 167315Sigor@sysoev.ru nxt_work_t *jobs); 16853Sigor@sysoev.ru 16953Sigor@sysoev.ru static void nxt_router_thread_start(void *data); 1701545Smax.romanov@nginx.com static void nxt_router_rt_add_port(nxt_task_t *task, void *obj, 1711545Smax.romanov@nginx.com void *data); 17253Sigor@sysoev.ru static void nxt_router_listen_socket_create(nxt_task_t *task, void *obj, 17353Sigor@sysoev.ru void *data); 17453Sigor@sysoev.ru static void nxt_router_listen_socket_update(nxt_task_t *task, void *obj, 17553Sigor@sysoev.ru void *data); 17653Sigor@sysoev.ru static void nxt_router_listen_socket_delete(nxt_task_t *task, void *obj, 17753Sigor@sysoev.ru void *data); 178313Sigor@sysoev.ru static void nxt_router_worker_thread_quit(nxt_task_t *task, void *obj, 179313Sigor@sysoev.ru void *data); 18053Sigor@sysoev.ru static void nxt_router_listen_socket_close(nxt_task_t *task, void *obj, 18153Sigor@sysoev.ru void *data); 18253Sigor@sysoev.ru static void nxt_router_thread_exit_handler(nxt_task_t *task, void *obj, 18353Sigor@sysoev.ru void *data); 1841547Smax.romanov@nginx.com static void nxt_router_req_headers_ack_handler(nxt_task_t *task, 1851547Smax.romanov@nginx.com nxt_port_recv_msg_t *msg, nxt_request_rpc_data_t *req_rpc_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 189630Svbart@nginx.com static void nxt_router_access_log_writer(nxt_task_t *task, 190630Svbart@nginx.com nxt_http_request_t *r, nxt_router_access_log_t *access_log); 191630Svbart@nginx.com static u_char *nxt_router_access_log_date(u_char *buf, nxt_realtime_t *now, 192630Svbart@nginx.com struct tm *tm, size_t size, const char *format); 193630Svbart@nginx.com static void nxt_router_access_log_open(nxt_task_t *task, 194630Svbart@nginx.com nxt_router_temp_conf_t *tmcf); 195630Svbart@nginx.com static void nxt_router_access_log_ready(nxt_task_t *task, 196630Svbart@nginx.com nxt_port_recv_msg_t *msg, void *data); 197630Svbart@nginx.com static void nxt_router_access_log_error(nxt_task_t *task, 198630Svbart@nginx.com nxt_port_recv_msg_t *msg, void *data); 199630Svbart@nginx.com static void nxt_router_access_log_release(nxt_task_t *task, 200630Svbart@nginx.com nxt_thread_spinlock_t *lock, nxt_router_access_log_t *access_log); 201651Svbart@nginx.com static void nxt_router_access_log_reopen_completion(nxt_task_t *task, void *obj, 202651Svbart@nginx.com void *data); 203631Svbart@nginx.com static void nxt_router_access_log_reopen_ready(nxt_task_t *task, 204631Svbart@nginx.com nxt_port_recv_msg_t *msg, void *data); 205631Svbart@nginx.com static void nxt_router_access_log_reopen_error(nxt_task_t *task, 206631Svbart@nginx.com nxt_port_recv_msg_t *msg, void *data); 207630Svbart@nginx.com 208343Smax.romanov@nginx.com static void nxt_router_app_port_ready(nxt_task_t *task, 209343Smax.romanov@nginx.com nxt_port_recv_msg_t *msg, void *data); 2101547Smax.romanov@nginx.com static nxt_int_t nxt_router_app_shared_port_send(nxt_task_t *task, 2111547Smax.romanov@nginx.com nxt_port_t *app_port); 212343Smax.romanov@nginx.com static void nxt_router_app_port_error(nxt_task_t *task, 213343Smax.romanov@nginx.com nxt_port_recv_msg_t *msg, void *data); 214343Smax.romanov@nginx.com 2151563Svbart@nginx.com static void nxt_router_app_use(nxt_task_t *task, nxt_app_t *app, int i); 216753Smax.romanov@nginx.com static void nxt_router_app_unlink(nxt_task_t *task, nxt_app_t *app); 2171123Smax.romanov@nginx.com 218343Smax.romanov@nginx.com static void nxt_router_app_port_release(nxt_task_t *task, nxt_port_t *port, 2191123Smax.romanov@nginx.com nxt_apr_action_t action); 2201547Smax.romanov@nginx.com static void nxt_router_app_port_get(nxt_task_t *task, nxt_app_t *app, 2211547Smax.romanov@nginx.com nxt_request_rpc_data_t *req_rpc_data); 2221561Smax.romanov@nginx.com static void nxt_router_http_request_error(nxt_task_t *task, void *obj, 2231561Smax.romanov@nginx.com void *data); 2241547Smax.romanov@nginx.com static void nxt_router_http_request_done(nxt_task_t *task, void *obj, 2251547Smax.romanov@nginx.com void *data); 226141Smax.romanov@nginx.com 2271566Smax.romanov@nginx.com static void nxt_router_dummy_buf_completion(nxt_task_t *task, void *obj, 2281566Smax.romanov@nginx.com void *data); 229425Smax.romanov@nginx.com static void nxt_router_app_prepare_request(nxt_task_t *task, 2301547Smax.romanov@nginx.com nxt_request_rpc_data_t *req_rpc_data); 2311007Salexander.borisov@nginx.com static nxt_buf_t *nxt_router_prepare_msg(nxt_task_t *task, 2321547Smax.romanov@nginx.com nxt_http_request_t *r, nxt_app_t *app, const nxt_str_t *prefix); 233510Salexander.borisov@nginx.com 234318Smax.romanov@nginx.com static void nxt_router_app_timeout(nxt_task_t *task, void *obj, void *data); 235507Smax.romanov@nginx.com static void nxt_router_adjust_idle_timer(nxt_task_t *task, void *obj, 236507Smax.romanov@nginx.com void *data); 237507Smax.romanov@nginx.com static void nxt_router_app_idle_timeout(nxt_task_t *task, void *obj, 238507Smax.romanov@nginx.com void *data); 239753Smax.romanov@nginx.com static void nxt_router_app_joint_release_handler(nxt_task_t *task, void *obj, 240507Smax.romanov@nginx.com void *data); 241753Smax.romanov@nginx.com static void nxt_router_free_app(nxt_task_t *task, void *obj, void *data); 242431Sigor@sysoev.ru 243431Sigor@sysoev.ru static const nxt_http_request_state_t nxt_http_request_send_state; 244431Sigor@sysoev.ru static void nxt_http_request_send_body(nxt_task_t *task, void *obj, void *data); 245141Smax.romanov@nginx.com 246753Smax.romanov@nginx.com static void nxt_router_app_joint_use(nxt_task_t *task, 247753Smax.romanov@nginx.com nxt_app_joint_t *app_joint, int i); 248753Smax.romanov@nginx.com 2491547Smax.romanov@nginx.com static void nxt_router_http_request_release_post(nxt_task_t *task, 2501007Salexander.borisov@nginx.com nxt_http_request_t *r); 2511007Salexander.borisov@nginx.com static void nxt_router_http_request_release(nxt_task_t *task, void *obj, 2521007Salexander.borisov@nginx.com void *data); 2531321Smax.romanov@nginx.com static void nxt_router_oosm_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg); 2541545Smax.romanov@nginx.com static void nxt_router_get_port_handler(nxt_task_t *task, 2551545Smax.romanov@nginx.com nxt_port_recv_msg_t *msg); 2561546Smax.romanov@nginx.com static void nxt_router_get_mmap_handler(nxt_task_t *task, 2571546Smax.romanov@nginx.com nxt_port_recv_msg_t *msg); 2581007Salexander.borisov@nginx.com 2591149Smax.romanov@nginx.com extern const nxt_http_request_state_t nxt_http_websocket; 2601131Smax.romanov@nginx.com 261119Smax.romanov@nginx.com static nxt_router_t *nxt_router; 26220Sigor@sysoev.ru 263743Smax.romanov@nginx.com static const nxt_str_t http_prefix = nxt_string("HTTP_"); 264743Smax.romanov@nginx.com static const nxt_str_t empty_prefix = nxt_string(""); 265743Smax.romanov@nginx.com 266743Smax.romanov@nginx.com static const nxt_str_t *nxt_app_msg_prefix[] = { 267804Svbart@nginx.com &empty_prefix, 2681594Smax.romanov@nginx.com &empty_prefix, 269743Smax.romanov@nginx.com &http_prefix, 270743Smax.romanov@nginx.com &http_prefix, 271743Smax.romanov@nginx.com &http_prefix, 272977Smax.romanov@gmail.com &empty_prefix, 273216Sigor@sysoev.ru }; 274216Sigor@sysoev.ru 275216Sigor@sysoev.ru 2761488St.nateldemoura@f5.com static const nxt_port_handlers_t nxt_router_process_port_handlers = { 2771488St.nateldemoura@f5.com .quit = nxt_signal_quit_handler, 278662Smax.romanov@nginx.com .new_port = nxt_router_new_port_handler, 2791545Smax.romanov@nginx.com .get_port = nxt_router_get_port_handler, 280662Smax.romanov@nginx.com .change_file = nxt_port_change_log_file_handler, 281662Smax.romanov@nginx.com .mmap = nxt_port_mmap_handler, 2821546Smax.romanov@nginx.com .get_mmap = nxt_router_get_mmap_handler, 283662Smax.romanov@nginx.com .data = nxt_router_conf_data_handler, 284662Smax.romanov@nginx.com .remove_pid = nxt_router_remove_pid_handler, 285662Smax.romanov@nginx.com .access_log = nxt_router_access_log_reopen_handler, 286662Smax.romanov@nginx.com .rpc_ready = nxt_port_rpc_handler, 287662Smax.romanov@nginx.com .rpc_error = nxt_port_rpc_handler, 2881321Smax.romanov@nginx.com .oosm = nxt_router_oosm_handler, 289662Smax.romanov@nginx.com }; 290662Smax.romanov@nginx.com 291662Smax.romanov@nginx.com 2921488St.nateldemoura@f5.com const nxt_process_init_t nxt_router_process = { 2931488St.nateldemoura@f5.com .name = "router", 2941488St.nateldemoura@f5.com .type = NXT_PROCESS_ROUTER, 2951488St.nateldemoura@f5.com .prefork = nxt_router_prefork, 2961488St.nateldemoura@f5.com .restart = 1, 2971488St.nateldemoura@f5.com .setup = nxt_process_core_setup, 2981488St.nateldemoura@f5.com .start = nxt_router_start, 2991488St.nateldemoura@f5.com .port_handlers = &nxt_router_process_port_handlers, 3001488St.nateldemoura@f5.com .signals = nxt_process_signals, 3011488St.nateldemoura@f5.com }; 3021488St.nateldemoura@f5.com 3031488St.nateldemoura@f5.com 3041509Sigor@sysoev.ru /* Queues of nxt_socket_conf_t */ 3051509Sigor@sysoev.ru nxt_queue_t creating_sockets; 3061509Sigor@sysoev.ru nxt_queue_t pending_sockets; 3071509Sigor@sysoev.ru nxt_queue_t updating_sockets; 3081509Sigor@sysoev.ru nxt_queue_t keeping_sockets; 3091509Sigor@sysoev.ru nxt_queue_t deleting_sockets; 3101509Sigor@sysoev.ru 3111509Sigor@sysoev.ru 3121488St.nateldemoura@f5.com static nxt_int_t 3131488St.nateldemoura@f5.com nxt_router_prefork(nxt_task_t *task, nxt_process_t *process, nxt_mp_t *mp) 3141488St.nateldemoura@f5.com { 3151488St.nateldemoura@f5.com nxt_runtime_stop_app_processes(task, task->thread->runtime); 3161488St.nateldemoura@f5.com 3171488St.nateldemoura@f5.com return NXT_OK; 3181488St.nateldemoura@f5.com } 3191488St.nateldemoura@f5.com 3201488St.nateldemoura@f5.com 3211488St.nateldemoura@f5.com static nxt_int_t 3221488St.nateldemoura@f5.com nxt_router_start(nxt_task_t *task, nxt_process_data_t *data) 32320Sigor@sysoev.ru { 324141Smax.romanov@nginx.com nxt_int_t ret; 325662Smax.romanov@nginx.com nxt_port_t *controller_port; 326141Smax.romanov@nginx.com nxt_router_t *router; 327141Smax.romanov@nginx.com nxt_runtime_t *rt; 328141Smax.romanov@nginx.com 329141Smax.romanov@nginx.com rt = task->thread->runtime; 33053Sigor@sysoev.ru 3311488St.nateldemoura@f5.com nxt_log(task, NXT_LOG_INFO, "router started"); 3321488St.nateldemoura@f5.com 333771Sigor@sysoev.ru #if (NXT_TLS) 334771Sigor@sysoev.ru rt->tls = nxt_service_get(rt->services, "SSL/TLS", "OpenSSL"); 335771Sigor@sysoev.ru if (nxt_slow_path(rt->tls == NULL)) { 336771Sigor@sysoev.ru return NXT_ERROR; 337771Sigor@sysoev.ru } 338771Sigor@sysoev.ru 339771Sigor@sysoev.ru ret = rt->tls->library_init(task); 340771Sigor@sysoev.ru if (nxt_slow_path(ret != NXT_OK)) { 341771Sigor@sysoev.ru return ret; 342771Sigor@sysoev.ru } 343771Sigor@sysoev.ru #endif 344771Sigor@sysoev.ru 3451459Smax.romanov@nginx.com ret = nxt_http_init(task); 34688Smax.romanov@nginx.com if (nxt_slow_path(ret != NXT_OK)) { 34788Smax.romanov@nginx.com return ret; 34888Smax.romanov@nginx.com } 34988Smax.romanov@nginx.com 35053Sigor@sysoev.ru router = nxt_zalloc(sizeof(nxt_router_t)); 35153Sigor@sysoev.ru if (nxt_slow_path(router == NULL)) { 35253Sigor@sysoev.ru return NXT_ERROR; 35353Sigor@sysoev.ru } 35453Sigor@sysoev.ru 35553Sigor@sysoev.ru nxt_queue_init(&router->engines); 35653Sigor@sysoev.ru nxt_queue_init(&router->sockets); 357133Sigor@sysoev.ru nxt_queue_init(&router->apps); 35853Sigor@sysoev.ru 359119Smax.romanov@nginx.com nxt_router = router; 360119Smax.romanov@nginx.com 361662Smax.romanov@nginx.com controller_port = rt->port_by_type[NXT_PROCESS_CONTROLLER]; 362662Smax.romanov@nginx.com if (controller_port != NULL) { 363662Smax.romanov@nginx.com nxt_router_greet_controller(task, controller_port); 364662Smax.romanov@nginx.com } 365662Smax.romanov@nginx.com 366115Sigor@sysoev.ru return NXT_OK; 367115Sigor@sysoev.ru } 368115Sigor@sysoev.ru 369115Sigor@sysoev.ru 370343Smax.romanov@nginx.com static void 371662Smax.romanov@nginx.com nxt_router_greet_controller(nxt_task_t *task, nxt_port_t *controller_port) 372662Smax.romanov@nginx.com { 373662Smax.romanov@nginx.com nxt_port_socket_write(task, controller_port, NXT_PORT_MSG_PROCESS_READY, 374662Smax.romanov@nginx.com -1, 0, 0, NULL); 375662Smax.romanov@nginx.com } 376662Smax.romanov@nginx.com 377662Smax.romanov@nginx.com 378662Smax.romanov@nginx.com static void 379507Smax.romanov@nginx.com nxt_router_start_app_process_handler(nxt_task_t *task, nxt_port_t *port, 380507Smax.romanov@nginx.com void *data) 381167Smax.romanov@nginx.com { 382343Smax.romanov@nginx.com size_t size; 383343Smax.romanov@nginx.com uint32_t stream; 384430Sigor@sysoev.ru nxt_mp_t *mp; 385648Svbart@nginx.com nxt_int_t ret; 386343Smax.romanov@nginx.com nxt_app_t *app; 387343Smax.romanov@nginx.com nxt_buf_t *b; 388343Smax.romanov@nginx.com nxt_port_t *main_port; 389343Smax.romanov@nginx.com nxt_runtime_t *rt; 390343Smax.romanov@nginx.com 391343Smax.romanov@nginx.com app = data; 392167Smax.romanov@nginx.com 393167Smax.romanov@nginx.com rt = task->thread->runtime; 394240Sigor@sysoev.ru main_port = rt->port_by_type[NXT_PROCESS_MAIN]; 395167Smax.romanov@nginx.com 396507Smax.romanov@nginx.com nxt_debug(task, "app '%V' %p start process", &app->name, app); 397343Smax.romanov@nginx.com 398343Smax.romanov@nginx.com size = app->name.length + 1 + app->conf.length; 399343Smax.romanov@nginx.com 400343Smax.romanov@nginx.com b = nxt_buf_mem_ts_alloc(task, task->thread->engine->mem_pool, size); 401343Smax.romanov@nginx.com 402343Smax.romanov@nginx.com if (nxt_slow_path(b == NULL)) { 403343Smax.romanov@nginx.com goto failed; 404167Smax.romanov@nginx.com } 405167Smax.romanov@nginx.com 406343Smax.romanov@nginx.com nxt_buf_cpystr(b, &app->name); 407343Smax.romanov@nginx.com *b->mem.free++ = '\0'; 408343Smax.romanov@nginx.com nxt_buf_cpystr(b, &app->conf); 409343Smax.romanov@nginx.com 410753Smax.romanov@nginx.com nxt_router_app_joint_use(task, app->joint, 1); 411753Smax.romanov@nginx.com 412343Smax.romanov@nginx.com stream = nxt_port_rpc_register_handler(task, port, 413343Smax.romanov@nginx.com nxt_router_app_port_ready, 414343Smax.romanov@nginx.com nxt_router_app_port_error, 415753Smax.romanov@nginx.com -1, app->joint); 416343Smax.romanov@nginx.com 417343Smax.romanov@nginx.com if (nxt_slow_path(stream == 0)) { 418753Smax.romanov@nginx.com nxt_router_app_joint_use(task, app->joint, -1); 419753Smax.romanov@nginx.com 420343Smax.romanov@nginx.com goto failed; 421343Smax.romanov@nginx.com } 422343Smax.romanov@nginx.com 4231488St.nateldemoura@f5.com ret = nxt_port_socket_write(task, main_port, NXT_PORT_MSG_START_PROCESS, 4241488St.nateldemoura@f5.com -1, stream, port->id, b); 425648Svbart@nginx.com 426648Svbart@nginx.com if (nxt_slow_path(ret != NXT_OK)) { 427648Svbart@nginx.com nxt_port_rpc_cancel(task, port, stream); 428753Smax.romanov@nginx.com 429753Smax.romanov@nginx.com nxt_router_app_joint_use(task, app->joint, -1); 430753Smax.romanov@nginx.com 431648Svbart@nginx.com goto failed; 432648Svbart@nginx.com } 433343Smax.romanov@nginx.com 434753Smax.romanov@nginx.com nxt_router_app_use(task, app, -1); 435753Smax.romanov@nginx.com 436343Smax.romanov@nginx.com return; 437343Smax.romanov@nginx.com 438343Smax.romanov@nginx.com failed: 439343Smax.romanov@nginx.com 440648Svbart@nginx.com if (b != NULL) { 441648Svbart@nginx.com mp = b->data; 442648Svbart@nginx.com nxt_mp_free(mp, b); 443648Svbart@nginx.com nxt_mp_release(mp); 444648Svbart@nginx.com } 445648Svbart@nginx.com 446343Smax.romanov@nginx.com nxt_thread_mutex_lock(&app->mutex); 447343Smax.romanov@nginx.com 448507Smax.romanov@nginx.com app->pending_processes--; 449343Smax.romanov@nginx.com 450343Smax.romanov@nginx.com nxt_thread_mutex_unlock(&app->mutex); 451343Smax.romanov@nginx.com 452343Smax.romanov@nginx.com nxt_router_app_use(task, app, -1); 453167Smax.romanov@nginx.com } 454167Smax.romanov@nginx.com 455167Smax.romanov@nginx.com 456753Smax.romanov@nginx.com static void 457753Smax.romanov@nginx.com nxt_router_app_joint_use(nxt_task_t *task, nxt_app_joint_t *app_joint, int i) 458753Smax.romanov@nginx.com { 459753Smax.romanov@nginx.com app_joint->use_count += i; 460753Smax.romanov@nginx.com 461753Smax.romanov@nginx.com if (app_joint->use_count == 0) { 462753Smax.romanov@nginx.com nxt_assert(app_joint->app == NULL); 463753Smax.romanov@nginx.com 464753Smax.romanov@nginx.com nxt_free(app_joint); 465753Smax.romanov@nginx.com } 466753Smax.romanov@nginx.com } 467753Smax.romanov@nginx.com 468753Smax.romanov@nginx.com 469343Smax.romanov@nginx.com static nxt_int_t 470507Smax.romanov@nginx.com nxt_router_start_app_process(nxt_task_t *task, nxt_app_t *app) 471141Smax.romanov@nginx.com { 472343Smax.romanov@nginx.com nxt_int_t res; 473343Smax.romanov@nginx.com nxt_port_t *router_port; 474343Smax.romanov@nginx.com nxt_runtime_t *rt; 475343Smax.romanov@nginx.com 4761549Smax.romanov@nginx.com nxt_debug(task, "app '%V' start process", &app->name); 4771549Smax.romanov@nginx.com 478343Smax.romanov@nginx.com rt = task->thread->runtime; 479343Smax.romanov@nginx.com router_port = rt->port_by_type[NXT_PROCESS_ROUTER]; 480343Smax.romanov@nginx.com 481343Smax.romanov@nginx.com nxt_router_app_use(task, app, 1); 482343Smax.romanov@nginx.com 483507Smax.romanov@nginx.com res = nxt_port_post(task, router_port, nxt_router_start_app_process_handler, 484343Smax.romanov@nginx.com app); 485343Smax.romanov@nginx.com 486343Smax.romanov@nginx.com if (res == NXT_OK) { 487343Smax.romanov@nginx.com return res; 488318Smax.romanov@nginx.com } 489318Smax.romanov@nginx.com 490343Smax.romanov@nginx.com nxt_thread_mutex_lock(&app->mutex); 491343Smax.romanov@nginx.com 492507Smax.romanov@nginx.com app->pending_processes--; 493343Smax.romanov@nginx.com 494343Smax.romanov@nginx.com nxt_thread_mutex_unlock(&app->mutex); 495343Smax.romanov@nginx.com 496343Smax.romanov@nginx.com nxt_router_app_use(task, app, -1); 497343Smax.romanov@nginx.com 498343Smax.romanov@nginx.com return NXT_ERROR; 499318Smax.romanov@nginx.com } 500318Smax.romanov@nginx.com 501318Smax.romanov@nginx.com 502423Smax.romanov@nginx.com nxt_inline nxt_bool_t 5031555Smax.romanov@nginx.com nxt_router_msg_cancel(nxt_task_t *task, nxt_request_rpc_data_t *req_rpc_data) 504423Smax.romanov@nginx.com { 5051555Smax.romanov@nginx.com nxt_buf_t *b, *next; 5061555Smax.romanov@nginx.com nxt_bool_t cancelled; 5071555Smax.romanov@nginx.com nxt_msg_info_t *msg_info; 5081555Smax.romanov@nginx.com 5091555Smax.romanov@nginx.com msg_info = &req_rpc_data->msg_info; 510423Smax.romanov@nginx.com 511423Smax.romanov@nginx.com if (msg_info->buf == NULL) { 512423Smax.romanov@nginx.com return 0; 513423Smax.romanov@nginx.com } 514423Smax.romanov@nginx.com 5151555Smax.romanov@nginx.com cancelled = nxt_app_queue_cancel(req_rpc_data->app->shared_port->queue, 5161555Smax.romanov@nginx.com msg_info->tracking_cookie, 5171555Smax.romanov@nginx.com req_rpc_data->stream); 518423Smax.romanov@nginx.com 519423Smax.romanov@nginx.com if (cancelled) { 5201555Smax.romanov@nginx.com nxt_debug(task, "stream #%uD: cancelled by router", 5211555Smax.romanov@nginx.com req_rpc_data->stream); 522423Smax.romanov@nginx.com } 523423Smax.romanov@nginx.com 524423Smax.romanov@nginx.com for (b = msg_info->buf; b != NULL; b = next) { 525423Smax.romanov@nginx.com next = b->next; 5261269Sigor@sysoev.ru b->next = NULL; 527423Smax.romanov@nginx.com 528423Smax.romanov@nginx.com if (b->is_port_mmap_sent) { 529423Smax.romanov@nginx.com b->is_port_mmap_sent = cancelled == 0; 530423Smax.romanov@nginx.com } 5311829Smax.romanov@nginx.com 5321829Smax.romanov@nginx.com b->completion_handler(task, b, b->parent); 533423Smax.romanov@nginx.com } 534423Smax.romanov@nginx.com 535423Smax.romanov@nginx.com msg_info->buf = NULL; 536423Smax.romanov@nginx.com 537423Smax.romanov@nginx.com return cancelled; 538423Smax.romanov@nginx.com } 539423Smax.romanov@nginx.com 540423Smax.romanov@nginx.com 541425Smax.romanov@nginx.com nxt_inline nxt_bool_t 542425Smax.romanov@nginx.com nxt_queue_chk_remove(nxt_queue_link_t *lnk) 543425Smax.romanov@nginx.com { 544425Smax.romanov@nginx.com if (lnk->next != NULL) { 545425Smax.romanov@nginx.com nxt_queue_remove(lnk); 546425Smax.romanov@nginx.com 547425Smax.romanov@nginx.com lnk->next = NULL; 548425Smax.romanov@nginx.com 549425Smax.romanov@nginx.com return 1; 550425Smax.romanov@nginx.com } 551425Smax.romanov@nginx.com 552425Smax.romanov@nginx.com return 0; 553425Smax.romanov@nginx.com } 554425Smax.romanov@nginx.com 555425Smax.romanov@nginx.com 556343Smax.romanov@nginx.com nxt_inline void 5571123Smax.romanov@nginx.com nxt_request_rpc_data_unlink(nxt_task_t *task, 5581123Smax.romanov@nginx.com nxt_request_rpc_data_t *req_rpc_data) 559343Smax.romanov@nginx.com { 5601561Smax.romanov@nginx.com nxt_app_t *app; 5611561Smax.romanov@nginx.com nxt_bool_t unlinked; 5621547Smax.romanov@nginx.com nxt_http_request_t *r; 5631547Smax.romanov@nginx.com 5641555Smax.romanov@nginx.com nxt_router_msg_cancel(task, req_rpc_data); 5651123Smax.romanov@nginx.com 5661123Smax.romanov@nginx.com if (req_rpc_data->app_port != NULL) { 5671123Smax.romanov@nginx.com nxt_router_app_port_release(task, req_rpc_data->app_port, 5681123Smax.romanov@nginx.com req_rpc_data->apr_action); 5691123Smax.romanov@nginx.com 5701123Smax.romanov@nginx.com req_rpc_data->app_port = NULL; 5711123Smax.romanov@nginx.com } 5721123Smax.romanov@nginx.com 5731561Smax.romanov@nginx.com app = req_rpc_data->app; 5741547Smax.romanov@nginx.com r = req_rpc_data->request; 5751547Smax.romanov@nginx.com 5761547Smax.romanov@nginx.com if (r != NULL) { 5771547Smax.romanov@nginx.com r->timer_data = NULL; 5781547Smax.romanov@nginx.com 5791547Smax.romanov@nginx.com nxt_router_http_request_release_post(task, r); 5801547Smax.romanov@nginx.com 5811547Smax.romanov@nginx.com r->req_rpc_data = NULL; 5821123Smax.romanov@nginx.com req_rpc_data->request = NULL; 5831561Smax.romanov@nginx.com 5841561Smax.romanov@nginx.com if (app != NULL) { 5851561Smax.romanov@nginx.com unlinked = 0; 5861561Smax.romanov@nginx.com 5871561Smax.romanov@nginx.com nxt_thread_mutex_lock(&app->mutex); 5881561Smax.romanov@nginx.com 5891561Smax.romanov@nginx.com if (r->app_link.next != NULL) { 5901561Smax.romanov@nginx.com nxt_queue_remove(&r->app_link); 5911561Smax.romanov@nginx.com r->app_link.next = NULL; 5921561Smax.romanov@nginx.com 5931561Smax.romanov@nginx.com unlinked = 1; 5941561Smax.romanov@nginx.com } 5951561Smax.romanov@nginx.com 5961561Smax.romanov@nginx.com nxt_thread_mutex_unlock(&app->mutex); 5971561Smax.romanov@nginx.com 5981561Smax.romanov@nginx.com if (unlinked) { 5991561Smax.romanov@nginx.com nxt_mp_release(r->mem_pool); 6001561Smax.romanov@nginx.com } 6011561Smax.romanov@nginx.com } 6021561Smax.romanov@nginx.com } 6031561Smax.romanov@nginx.com 6041561Smax.romanov@nginx.com if (app != NULL) { 6051561Smax.romanov@nginx.com nxt_router_app_use(task, app, -1); 6061561Smax.romanov@nginx.com 6071561Smax.romanov@nginx.com req_rpc_data->app = NULL; 608346Smax.romanov@nginx.com } 6091547Smax.romanov@nginx.com 6101547Smax.romanov@nginx.com if (req_rpc_data->msg_info.body_fd != -1) { 6111547Smax.romanov@nginx.com nxt_fd_close(req_rpc_data->msg_info.body_fd); 6121547Smax.romanov@nginx.com 6131547Smax.romanov@nginx.com req_rpc_data->msg_info.body_fd = -1; 6141547Smax.romanov@nginx.com } 6151547Smax.romanov@nginx.com 6161547Smax.romanov@nginx.com if (req_rpc_data->rpc_cancel) { 6171547Smax.romanov@nginx.com req_rpc_data->rpc_cancel = 0; 6181547Smax.romanov@nginx.com 6191547Smax.romanov@nginx.com nxt_port_rpc_cancel(task, task->thread->engine->port, 6201547Smax.romanov@nginx.com req_rpc_data->stream); 6211547Smax.romanov@nginx.com } 622343Smax.romanov@nginx.com } 623343Smax.romanov@nginx.com 624343Smax.romanov@nginx.com 6251552Smax.romanov@nginx.com static void 626141Smax.romanov@nginx.com nxt_router_new_port_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg) 627141Smax.romanov@nginx.com { 6281555Smax.romanov@nginx.com nxt_int_t res; 6291547Smax.romanov@nginx.com nxt_app_t *app; 6301547Smax.romanov@nginx.com nxt_port_t *port, *main_app_port; 6311547Smax.romanov@nginx.com nxt_runtime_t *rt; 6321547Smax.romanov@nginx.com 633141Smax.romanov@nginx.com nxt_port_new_port_handler(task, msg); 634141Smax.romanov@nginx.com 6351547Smax.romanov@nginx.com port = msg->u.new_port; 6361547Smax.romanov@nginx.com 6371547Smax.romanov@nginx.com if (port != NULL && port->type == NXT_PROCESS_CONTROLLER) { 638662Smax.romanov@nginx.com nxt_router_greet_controller(task, msg->u.new_port); 639662Smax.romanov@nginx.com } 640662Smax.romanov@nginx.com 6411547Smax.romanov@nginx.com if (port == NULL || port->type != NXT_PROCESS_APP) { 6421547Smax.romanov@nginx.com 6431547Smax.romanov@nginx.com if (msg->port_msg.stream == 0) { 6441547Smax.romanov@nginx.com return; 6451547Smax.romanov@nginx.com } 6461547Smax.romanov@nginx.com 6471547Smax.romanov@nginx.com msg->port_msg.type = _NXT_PORT_MSG_RPC_ERROR; 6481555Smax.romanov@nginx.com 6491555Smax.romanov@nginx.com } else { 6501558Smax.romanov@nginx.com if (msg->fd[1] != -1) { 6511558Smax.romanov@nginx.com res = nxt_router_port_queue_map(task, port, msg->fd[1]); 6521555Smax.romanov@nginx.com if (nxt_slow_path(res != NXT_OK)) { 6531555Smax.romanov@nginx.com return; 6541555Smax.romanov@nginx.com } 6551555Smax.romanov@nginx.com 6561558Smax.romanov@nginx.com nxt_fd_close(msg->fd[1]); 6571558Smax.romanov@nginx.com msg->fd[1] = -1; 6581555Smax.romanov@nginx.com } 6591547Smax.romanov@nginx.com } 6601547Smax.romanov@nginx.com 6611547Smax.romanov@nginx.com if (msg->port_msg.stream != 0) { 6621547Smax.romanov@nginx.com nxt_port_rpc_handler(task, msg); 663141Smax.romanov@nginx.com return; 664141Smax.romanov@nginx.com } 665141Smax.romanov@nginx.com 6661547Smax.romanov@nginx.com /* 6671547Smax.romanov@nginx.com * Port with "id == 0" is application 'main' port and it always 6681547Smax.romanov@nginx.com * should come with non-zero stream. 6691547Smax.romanov@nginx.com */ 6701547Smax.romanov@nginx.com nxt_assert(port->id != 0); 6711547Smax.romanov@nginx.com 6721547Smax.romanov@nginx.com /* Find 'main' app port and get app reference. */ 6731547Smax.romanov@nginx.com rt = task->thread->runtime; 6741547Smax.romanov@nginx.com 6751547Smax.romanov@nginx.com /* 6761547Smax.romanov@nginx.com * It is safe to access 'runtime->ports' hash because 'NEW_PORT' 6771547Smax.romanov@nginx.com * sent to main port (with id == 0) and processed in main thread. 6781547Smax.romanov@nginx.com */ 6791547Smax.romanov@nginx.com main_app_port = nxt_port_hash_find(&rt->ports, port->pid, 0); 6801547Smax.romanov@nginx.com nxt_assert(main_app_port != NULL); 6811547Smax.romanov@nginx.com 6821547Smax.romanov@nginx.com app = main_app_port->app; 683*1915Smax.romanov@nginx.com 684*1915Smax.romanov@nginx.com if (nxt_fast_path(app != NULL)) { 685*1915Smax.romanov@nginx.com nxt_thread_mutex_lock(&app->mutex); 686*1915Smax.romanov@nginx.com 687*1915Smax.romanov@nginx.com /* TODO here should be find-and-add code because there can be 688*1915Smax.romanov@nginx.com port waiters in port_hash */ 689*1915Smax.romanov@nginx.com nxt_port_hash_add(&app->port_hash, port); 690*1915Smax.romanov@nginx.com app->port_hash_count++; 691*1915Smax.romanov@nginx.com 692*1915Smax.romanov@nginx.com nxt_thread_mutex_unlock(&app->mutex); 693*1915Smax.romanov@nginx.com 694*1915Smax.romanov@nginx.com port->app = app; 695*1915Smax.romanov@nginx.com } 696*1915Smax.romanov@nginx.com 6971547Smax.romanov@nginx.com port->main_app_port = main_app_port; 6981666Smax.romanov@nginx.com 6991666Smax.romanov@nginx.com nxt_port_socket_write(task, port, NXT_PORT_MSG_PORT_ACK, -1, 0, 0, NULL); 700141Smax.romanov@nginx.com } 701141Smax.romanov@nginx.com 702141Smax.romanov@nginx.com 7031552Smax.romanov@nginx.com static void 704139Sigor@sysoev.ru nxt_router_conf_data_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg) 705115Sigor@sysoev.ru { 7061526Smax.romanov@nginx.com void *p; 7071526Smax.romanov@nginx.com size_t size; 708198Sigor@sysoev.ru nxt_int_t ret; 7091779Smax.romanov@nginx.com nxt_port_t *port; 710139Sigor@sysoev.ru nxt_router_temp_conf_t *tmcf; 711139Sigor@sysoev.ru 7121779Smax.romanov@nginx.com port = nxt_runtime_port_find(task->thread->runtime, 7131779Smax.romanov@nginx.com msg->port_msg.pid, 7141779Smax.romanov@nginx.com msg->port_msg.reply_port); 7151779Smax.romanov@nginx.com if (nxt_slow_path(port == NULL)) { 7161779Smax.romanov@nginx.com nxt_alert(task, "conf_data_handler: reply port not found"); 7171779Smax.romanov@nginx.com return; 7181779Smax.romanov@nginx.com } 7191779Smax.romanov@nginx.com 7201779Smax.romanov@nginx.com p =