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> 1820Sigor@sysoev.ru 19115Sigor@sysoev.ru typedef struct { 20318Smax.romanov@nginx.com nxt_str_t type; 21507Smax.romanov@nginx.com uint32_t processes; 22507Smax.romanov@nginx.com uint32_t max_processes; 23507Smax.romanov@nginx.com uint32_t spare_processes; 24318Smax.romanov@nginx.com nxt_msec_t timeout; 25427Smax.romanov@nginx.com nxt_msec_t res_timeout; 26507Smax.romanov@nginx.com nxt_msec_t idle_timeout; 27318Smax.romanov@nginx.com uint32_t requests; 28318Smax.romanov@nginx.com nxt_conf_value_t *limits_value; 29507Smax.romanov@nginx.com nxt_conf_value_t *processes_value; 30*1473Svbart@nginx.com nxt_conf_value_t *targets_value; 31133Sigor@sysoev.ru } nxt_router_app_conf_t; 32133Sigor@sysoev.ru 33133Sigor@sysoev.ru 34133Sigor@sysoev.ru typedef struct { 35964Sigor@sysoev.ru nxt_str_t pass; 36964Sigor@sysoev.ru nxt_str_t application; 37115Sigor@sysoev.ru } nxt_router_listener_conf_t; 38115Sigor@sysoev.ru 39115Sigor@sysoev.ru 40774Svbart@nginx.com #if (NXT_TLS) 41774Svbart@nginx.com 42774Svbart@nginx.com typedef struct { 43774Svbart@nginx.com nxt_str_t name; 44774Svbart@nginx.com nxt_socket_conf_t *conf; 45774Svbart@nginx.com 46774Svbart@nginx.com nxt_queue_link_t link; /* for nxt_socket_conf_t.tls */ 47774Svbart@nginx.com } nxt_router_tlssock_t; 48774Svbart@nginx.com 49774Svbart@nginx.com #endif 50774Svbart@nginx.com 51774Svbart@nginx.com 52198Sigor@sysoev.ru typedef struct { 53198Sigor@sysoev.ru nxt_socket_conf_t *socket_conf; 54198Sigor@sysoev.ru nxt_router_temp_conf_t *temp_conf; 55198Sigor@sysoev.ru } nxt_socket_rpc_t; 56198Sigor@sysoev.ru 57198Sigor@sysoev.ru 58507Smax.romanov@nginx.com typedef struct { 59507Smax.romanov@nginx.com nxt_app_t *app; 60507Smax.romanov@nginx.com nxt_router_temp_conf_t *temp_conf; 61507Smax.romanov@nginx.com } nxt_app_rpc_t; 62507Smax.romanov@nginx.com 63507Smax.romanov@nginx.com 64427Smax.romanov@nginx.com struct nxt_port_select_state_s { 651123Smax.romanov@nginx.com nxt_app_t *app; 661123Smax.romanov@nginx.com nxt_request_app_link_t *req_app_link; 671123Smax.romanov@nginx.com 681123Smax.romanov@nginx.com nxt_port_t *failed_port; 691123Smax.romanov@nginx.com int failed_port_use_delta; 701123Smax.romanov@nginx.com 711123Smax.romanov@nginx.com uint8_t start_process; /* 1 bit */ 721123Smax.romanov@nginx.com nxt_request_app_link_t *shared_ra; 731123Smax.romanov@nginx.com nxt_port_t *port; 74427Smax.romanov@nginx.com }; 75427Smax.romanov@nginx.com 76427Smax.romanov@nginx.com typedef struct nxt_port_select_state_s nxt_port_select_state_t; 77427Smax.romanov@nginx.com 78662Smax.romanov@nginx.com static void nxt_router_greet_controller(nxt_task_t *task, 79662Smax.romanov@nginx.com nxt_port_t *controller_port); 80662Smax.romanov@nginx.com 81427Smax.romanov@nginx.com static void nxt_router_port_select(nxt_task_t *task, 82427Smax.romanov@nginx.com nxt_port_select_state_t *state); 83427Smax.romanov@nginx.com 84427Smax.romanov@nginx.com static nxt_int_t nxt_router_port_post_select(nxt_task_t *task, 85427Smax.romanov@nginx.com nxt_port_select_state_t *state); 86427Smax.romanov@nginx.com 87507Smax.romanov@nginx.com static nxt_int_t nxt_router_start_app_process(nxt_task_t *task, nxt_app_t *app); 881123Smax.romanov@nginx.com static void nxt_request_app_link_update_peer(nxt_task_t *task, 891123Smax.romanov@nginx.com nxt_request_app_link_t *req_app_link); 901123Smax.romanov@nginx.com 91343Smax.romanov@nginx.com 92425Smax.romanov@nginx.com nxt_inline void 931123Smax.romanov@nginx.com nxt_request_app_link_inc_use(nxt_request_app_link_t *req_app_link) 94425Smax.romanov@nginx.com { 951123Smax.romanov@nginx.com nxt_atomic_fetch_add(&req_app_link->use_count, 1); 96425Smax.romanov@nginx.com } 97425Smax.romanov@nginx.com 98425Smax.romanov@nginx.com nxt_inline void 991294Smax.romanov@nginx.com nxt_request_app_link_chk_use(nxt_request_app_link_t *req_app_link, int i) 100425Smax.romanov@nginx.com { 101538Svbart@nginx.com #if (NXT_DEBUG) 102425Smax.romanov@nginx.com int c; 103425Smax.romanov@nginx.com 1041294Smax.romanov@nginx.com c = nxt_atomic_fetch_add(&req_app_link->use_count, i); 1051294Smax.romanov@nginx.com 1061294Smax.romanov@nginx.com nxt_assert((c + i) > 0); 107538Svbart@nginx.com #else 1081294Smax.romanov@nginx.com (void) nxt_atomic_fetch_add(&req_app_link->use_count, i); 109538Svbart@nginx.com #endif 110425Smax.romanov@nginx.com } 111425Smax.romanov@nginx.com 1121123Smax.romanov@nginx.com static void nxt_request_app_link_use(nxt_task_t *task, 1131123Smax.romanov@nginx.com nxt_request_app_link_t *req_app_link, int i); 114425Smax.romanov@nginx.com 115139Sigor@sysoev.ru static nxt_router_temp_conf_t *nxt_router_temp_conf(nxt_task_t *task); 116198Sigor@sysoev.ru static void nxt_router_conf_apply(nxt_task_t *task, void *obj, void *data); 117198Sigor@sysoev.ru static void nxt_router_conf_ready(nxt_task_t *task, 118139Sigor@sysoev.ru nxt_router_temp_conf_t *tmcf); 119139Sigor@sysoev.ru static void nxt_router_conf_error(nxt_task_t *task, 120139Sigor@sysoev.ru nxt_router_temp_conf_t *tmcf); 121139Sigor@sysoev.ru static void nxt_router_conf_send(nxt_task_t *task, 122193Smax.romanov@nginx.com nxt_router_temp_conf_t *tmcf, nxt_port_msg_type_t type); 12353Sigor@sysoev.ru 124115Sigor@sysoev.ru static nxt_int_t nxt_router_conf_create(nxt_task_t *task, 125115Sigor@sysoev.ru nxt_router_temp_conf_t *tmcf, u_char *start, u_char *end); 1261183Svbart@nginx.com static nxt_int_t nxt_router_conf_process_static(nxt_task_t *task, 1271183Svbart@nginx.com nxt_router_conf_t *rtcf, nxt_conf_value_t *conf); 128133Sigor@sysoev.ru static nxt_app_t *nxt_router_app_find(nxt_queue_t *queue, nxt_str_t *name); 129198Sigor@sysoev.ru static void nxt_router_listen_socket_rpc_create(nxt_task_t *task, 130198Sigor@sysoev.ru nxt_router_temp_conf_t *tmcf, nxt_socket_conf_t *skcf); 131198Sigor@sysoev.ru static void nxt_router_listen_socket_ready(nxt_task_t *task, 132198Sigor@sysoev.ru nxt_port_recv_msg_t *msg, void *data); 133198Sigor@sysoev.ru static void nxt_router_listen_socket_error(nxt_task_t *task, 134198Sigor@sysoev.ru nxt_port_recv_msg_t *msg, void *data); 135774Svbart@nginx.com #if (NXT_TLS) 136774Svbart@nginx.com static void nxt_router_tls_rpc_create(nxt_task_t *task, 137774Svbart@nginx.com nxt_router_temp_conf_t *tmcf, nxt_router_tlssock_t *tls); 138774Svbart@nginx.com static void nxt_router_tls_rpc_handler(nxt_task_t *task, 139774Svbart@nginx.com nxt_port_recv_msg_t *msg, void *data); 140774Svbart@nginx.com #endif 141507Smax.romanov@nginx.com static void nxt_router_app_rpc_create(nxt_task_t *task, 142507Smax.romanov@nginx.com nxt_router_temp_conf_t *tmcf, nxt_app_t *app); 143507Smax.romanov@nginx.com static void nxt_router_app_prefork_ready(nxt_task_t *task, 144507Smax.romanov@nginx.com nxt_port_recv_msg_t *msg, void *data); 145507Smax.romanov@nginx.com static void nxt_router_app_prefork_error(nxt_task_t *task, 146507Smax.romanov@nginx.com nxt_port_recv_msg_t *msg, void *data); 147359Sigor@sysoev.ru static nxt_socket_conf_t *nxt_router_socket_conf(nxt_task_t *task, 148359Sigor@sysoev.ru nxt_router_temp_conf_t *tmcf, nxt_str_t *name); 149359Sigor@sysoev.ru static nxt_int_t nxt_router_listen_socket_find(nxt_router_temp_conf_t *tmcf, 150359Sigor@sysoev.ru nxt_socket_conf_t *nskcf, nxt_sockaddr_t *sa); 15153Sigor@sysoev.ru 15253Sigor@sysoev.ru static nxt_int_t nxt_router_engines_create(nxt_task_t *task, 15353Sigor@sysoev.ru nxt_router_t *router, nxt_router_temp_conf_t *tmcf, 15453Sigor@sysoev.ru const nxt_event_interface_t *interface); 155115Sigor@sysoev.ru static nxt_int_t nxt_router_engine_conf_create(nxt_router_temp_conf_t *tmcf, 156115Sigor@sysoev.ru nxt_router_engine_conf_t *recf); 157115Sigor@sysoev.ru static nxt_int_t nxt_router_engine_conf_update(nxt_router_temp_conf_t *tmcf, 158115Sigor@sysoev.ru nxt_router_engine_conf_t *recf); 159115Sigor@sysoev.ru static nxt_int_t nxt_router_engine_conf_delete(nxt_router_temp_conf_t *tmcf, 160115Sigor@sysoev.ru nxt_router_engine_conf_t *recf); 161154Sigor@sysoev.ru static nxt_int_t nxt_router_engine_joints_create(nxt_router_temp_conf_t *tmcf, 162154Sigor@sysoev.ru nxt_router_engine_conf_t *recf, nxt_queue_t *sockets, 163154Sigor@sysoev.ru nxt_work_handler_t handler); 164313Sigor@sysoev.ru static nxt_int_t nxt_router_engine_quit(nxt_router_temp_conf_t *tmcf, 165313Sigor@sysoev.ru nxt_router_engine_conf_t *recf); 166139Sigor@sysoev.ru static nxt_int_t nxt_router_engine_joints_delete(nxt_router_temp_conf_t *tmcf, 167139Sigor@sysoev.ru nxt_router_engine_conf_t *recf, nxt_queue_t *sockets); 16853Sigor@sysoev.ru 16953Sigor@sysoev.ru static nxt_int_t nxt_router_threads_create(nxt_task_t *task, nxt_runtime_t *rt, 17053Sigor@sysoev.ru nxt_router_temp_conf_t *tmcf); 17153Sigor@sysoev.ru static nxt_int_t nxt_router_thread_create(nxt_task_t *task, nxt_runtime_t *rt, 17253Sigor@sysoev.ru nxt_event_engine_t *engine); 173343Smax.romanov@nginx.com static void nxt_router_apps_sort(nxt_task_t *task, nxt_router_t *router, 174133Sigor@sysoev.ru nxt_router_temp_conf_t *tmcf); 17553Sigor@sysoev.ru 176315Sigor@sysoev.ru static void nxt_router_engines_post(nxt_router_t *router, 177315Sigor@sysoev.ru nxt_router_temp_conf_t *tmcf); 178315Sigor@sysoev.ru static void nxt_router_engine_post(nxt_event_engine_t *engine, 179315Sigor@sysoev.ru nxt_work_t *jobs); 18053Sigor@sysoev.ru 18153Sigor@sysoev.ru static void nxt_router_thread_start(void *data); 18253Sigor@sysoev.ru static void nxt_router_listen_socket_create(nxt_task_t *task, void *obj, 18353Sigor@sysoev.ru void *data); 18453Sigor@sysoev.ru static void nxt_router_listen_socket_update(nxt_task_t *task, void *obj, 18553Sigor@sysoev.ru void *data); 18653Sigor@sysoev.ru static void nxt_router_listen_socket_delete(nxt_task_t *task, void *obj, 18753Sigor@sysoev.ru void *data); 188313Sigor@sysoev.ru static void nxt_router_worker_thread_quit(nxt_task_t *task, void *obj, 189313Sigor@sysoev.ru void *data); 19053Sigor@sysoev.ru static void nxt_router_listen_socket_close(nxt_task_t *task, void *obj, 19153Sigor@sysoev.ru void *data); 19253Sigor@sysoev.ru static void nxt_router_thread_exit_handler(nxt_task_t *task, void *obj, 19353Sigor@sysoev.ru void *data); 194359Sigor@sysoev.ru static void nxt_router_listen_socket_release(nxt_task_t *task, 195359Sigor@sysoev.ru nxt_socket_conf_t *skcf); 19653Sigor@sysoev.ru 197630Svbart@nginx.com static void nxt_router_access_log_writer(nxt_task_t *task, 198630Svbart@nginx.com nxt_http_request_t *r, nxt_router_access_log_t *access_log); 199630Svbart@nginx.com static u_char *nxt_router_access_log_date(u_char *buf, nxt_realtime_t *now, 200630Svbart@nginx.com struct tm *tm, size_t size, const char *format); 201630Svbart@nginx.com static void nxt_router_access_log_open(nxt_task_t *task, 202630Svbart@nginx.com nxt_router_temp_conf_t *tmcf); 203630Svbart@nginx.com static void nxt_router_access_log_ready(nxt_task_t *task, 204630Svbart@nginx.com nxt_port_recv_msg_t *msg, void *data); 205630Svbart@nginx.com static void nxt_router_access_log_error(nxt_task_t *task, 206630Svbart@nginx.com nxt_port_recv_msg_t *msg, void *data); 207630Svbart@nginx.com static void nxt_router_access_log_release(nxt_task_t *task, 208630Svbart@nginx.com nxt_thread_spinlock_t *lock, nxt_router_access_log_t *access_log); 209651Svbart@nginx.com static void nxt_router_access_log_reopen_completion(nxt_task_t *task, void *obj, 210651Svbart@nginx.com void *data); 211631Svbart@nginx.com static void nxt_router_access_log_reopen_ready(nxt_task_t *task, 212631Svbart@nginx.com nxt_port_recv_msg_t *msg, void *data); 213631Svbart@nginx.com static void nxt_router_access_log_reopen_error(nxt_task_t *task, 214631Svbart@nginx.com nxt_port_recv_msg_t *msg, void *data); 215630Svbart@nginx.com 216343Smax.romanov@nginx.com static void nxt_router_app_port_ready(nxt_task_t *task, 217343Smax.romanov@nginx.com nxt_port_recv_msg_t *msg, void *data); 218343Smax.romanov@nginx.com static void nxt_router_app_port_error(nxt_task_t *task, 219343Smax.romanov@nginx.com nxt_port_recv_msg_t *msg, void *data); 220343Smax.romanov@nginx.com 221753Smax.romanov@nginx.com static void nxt_router_app_unlink(nxt_task_t *task, nxt_app_t *app); 2221123Smax.romanov@nginx.com 223343Smax.romanov@nginx.com static void nxt_router_app_port_release(nxt_task_t *task, nxt_port_t *port, 2241123Smax.romanov@nginx.com nxt_apr_action_t action); 225427Smax.romanov@nginx.com static nxt_int_t nxt_router_app_port(nxt_task_t *task, nxt_app_t *app, 2261123Smax.romanov@nginx.com nxt_request_app_link_t *req_app_link); 227141Smax.romanov@nginx.com 228425Smax.romanov@nginx.com static void nxt_router_app_prepare_request(nxt_task_t *task, 2291123Smax.romanov@nginx.com nxt_request_app_link_t *req_app_link); 2301007Salexander.borisov@nginx.com static nxt_buf_t *nxt_router_prepare_msg(nxt_task_t *task, 2311007Salexander.borisov@nginx.com nxt_http_request_t *r, nxt_port_t *port, const nxt_str_t *prefix); 232510Salexander.borisov@nginx.com 233318Smax.romanov@nginx.com static void nxt_router_app_timeout(nxt_task_t *task, void *obj, void *data); 234507Smax.romanov@nginx.com static void nxt_router_adjust_idle_timer(nxt_task_t *task, void *obj, 235507Smax.romanov@nginx.com void *data); 236507Smax.romanov@nginx.com static void nxt_router_app_idle_timeout(nxt_task_t *task, void *obj, 237507Smax.romanov@nginx.com void *data); 238753Smax.romanov@nginx.com static void nxt_router_app_joint_release_handler(nxt_task_t *task, void *obj, 239507Smax.romanov@nginx.com void *data); 240753Smax.romanov@nginx.com static void nxt_router_free_app(nxt_task_t *task, void *obj, void *data); 241431Sigor@sysoev.ru 242431Sigor@sysoev.ru static const nxt_http_request_state_t nxt_http_request_send_state; 243431Sigor@sysoev.ru static void nxt_http_request_send_body(nxt_task_t *task, void *obj, void *data); 244141Smax.romanov@nginx.com 245753Smax.romanov@nginx.com static void nxt_router_app_joint_use(nxt_task_t *task, 246753Smax.romanov@nginx.com nxt_app_joint_t *app_joint, int i); 247753Smax.romanov@nginx.com 2481007Salexander.borisov@nginx.com static nxt_int_t nxt_router_http_request_done(nxt_task_t *task, 2491007Salexander.borisov@nginx.com nxt_http_request_t *r); 2501007Salexander.borisov@nginx.com static void nxt_router_http_request_release(nxt_task_t *task, void *obj, 2511007Salexander.borisov@nginx.com void *data); 2521321Smax.romanov@nginx.com static void nxt_router_oosm_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg); 2531007Salexander.borisov@nginx.com 2541149Smax.romanov@nginx.com extern const nxt_http_request_state_t nxt_http_websocket; 2551131Smax.romanov@nginx.com 256119Smax.romanov@nginx.com static nxt_router_t *nxt_router; 25720Sigor@sysoev.ru 258743Smax.romanov@nginx.com static const nxt_str_t http_prefix = nxt_string("HTTP_"); 259743Smax.romanov@nginx.com static const nxt_str_t empty_prefix = nxt_string(""); 260743Smax.romanov@nginx.com 261743Smax.romanov@nginx.com static const nxt_str_t *nxt_app_msg_prefix[] = { 262804Svbart@nginx.com &empty_prefix, 263743Smax.romanov@nginx.com &http_prefix, 264743Smax.romanov@nginx.com &http_prefix, 265743Smax.romanov@nginx.com &http_prefix, 266743Smax.romanov@nginx.com &http_prefix, 267977Smax.romanov@gmail.com &empty_prefix, 268216Sigor@sysoev.ru }; 269216Sigor@sysoev.ru 270216Sigor@sysoev.ru 271662Smax.romanov@nginx.com nxt_port_handlers_t nxt_router_process_port_handlers = { 272662Smax.romanov@nginx.com .quit = nxt_worker_process_quit_handler, 273662Smax.romanov@nginx.com .new_port = nxt_router_new_port_handler, 274662Smax.romanov@nginx.com .change_file = nxt_port_change_log_file_handler, 275662Smax.romanov@nginx.com .mmap = nxt_port_mmap_handler, 276662Smax.romanov@nginx.com .data = nxt_router_conf_data_handler, 277662Smax.romanov@nginx.com .remove_pid = nxt_router_remove_pid_handler, 278662Smax.romanov@nginx.com .access_log = nxt_router_access_log_reopen_handler, 279662Smax.romanov@nginx.com .rpc_ready = nxt_port_rpc_handler, 280662Smax.romanov@nginx.com .rpc_error = nxt_port_rpc_handler, 2811321Smax.romanov@nginx.com .oosm = nxt_router_oosm_handler, 282662Smax.romanov@nginx.com }; 283662Smax.romanov@nginx.com 284662Smax.romanov@nginx.com 28520Sigor@sysoev.ru nxt_int_t 286141Smax.romanov@nginx.com nxt_router_start(nxt_task_t *task, void *data) 28720Sigor@sysoev.ru { 288141Smax.romanov@nginx.com nxt_int_t ret; 289662Smax.romanov@nginx.com nxt_port_t *controller_port; 290141Smax.romanov@nginx.com nxt_router_t *router; 291141Smax.romanov@nginx.com nxt_runtime_t *rt; 292141Smax.romanov@nginx.com 293141Smax.romanov@nginx.com rt = task->thread->runtime; 29453Sigor@sysoev.ru 295771Sigor@sysoev.ru #if (NXT_TLS) 296771Sigor@sysoev.ru rt->tls = nxt_service_get(rt->services, "SSL/TLS", "OpenSSL"); 297771Sigor@sysoev.ru if (nxt_slow_path(rt->tls == NULL)) { 298771Sigor@sysoev.ru return NXT_ERROR; 299771Sigor@sysoev.ru } 300771Sigor@sysoev.ru 301771Sigor@sysoev.ru ret = rt->tls->library_init(task); 302771Sigor@sysoev.ru if (nxt_slow_path(ret != NXT_OK)) { 303771Sigor@sysoev.ru return ret; 304771Sigor@sysoev.ru } 305771Sigor@sysoev.ru #endif 306771Sigor@sysoev.ru 3071459Smax.romanov@nginx.com ret = nxt_http_init(task); 30888Smax.romanov@nginx.com if (nxt_slow_path(ret != NXT_OK)) { 30988Smax.romanov@nginx.com return ret; 31088Smax.romanov@nginx.com } 31188Smax.romanov@nginx.com 31253Sigor@sysoev.ru router = nxt_zalloc(sizeof(nxt_router_t)); 31353Sigor@sysoev.ru if (nxt_slow_path(router == NULL)) { 31453Sigor@sysoev.ru return NXT_ERROR; 31553Sigor@sysoev.ru } 31653Sigor@sysoev.ru 31753Sigor@sysoev.ru nxt_queue_init(&router->engines); 31853Sigor@sysoev.ru nxt_queue_init(&router->sockets); 319133Sigor@sysoev.ru nxt_queue_init(&router->apps); 32053Sigor@sysoev.ru 321119Smax.romanov@nginx.com nxt_router = router; 322119Smax.romanov@nginx.com 323662Smax.romanov@nginx.com controller_port = rt->port_by_type[NXT_PROCESS_CONTROLLER]; 324662Smax.romanov@nginx.com if (controller_port != NULL) { 325662Smax.romanov@nginx.com nxt_router_greet_controller(task, controller_port); 326662Smax.romanov@nginx.com } 327662Smax.romanov@nginx.com 328115Sigor@sysoev.ru return NXT_OK; 329115Sigor@sysoev.ru } 330115Sigor@sysoev.ru 331115Sigor@sysoev.ru 332343Smax.romanov@nginx.com static void 333662Smax.romanov@nginx.com nxt_router_greet_controller(nxt_task_t *task, nxt_port_t *controller_port) 334662Smax.romanov@nginx.com { 335662Smax.romanov@nginx.com nxt_port_socket_write(task, controller_port, NXT_PORT_MSG_PROCESS_READY, 336662Smax.romanov@nginx.com -1, 0, 0, NULL); 337662Smax.romanov@nginx.com } 338662Smax.romanov@nginx.com 339662Smax.romanov@nginx.com 340662Smax.romanov@nginx.com static void 341507Smax.romanov@nginx.com nxt_router_start_app_process_handler(nxt_task_t *task, nxt_port_t *port, 342507Smax.romanov@nginx.com void *data) 343167Smax.romanov@nginx.com { 344343Smax.romanov@nginx.com size_t size; 345343Smax.romanov@nginx.com uint32_t stream; 346430Sigor@sysoev.ru nxt_mp_t *mp; 347648Svbart@nginx.com nxt_int_t ret; 348343Smax.romanov@nginx.com nxt_app_t *app; 349343Smax.romanov@nginx.com nxt_buf_t *b; 350343Smax.romanov@nginx.com nxt_port_t *main_port; 351343Smax.romanov@nginx.com nxt_runtime_t *rt; 352343Smax.romanov@nginx.com 353343Smax.romanov@nginx.com app = data; 354167Smax.romanov@nginx.com 355167Smax.romanov@nginx.com rt = task->thread->runtime; 356240Sigor@sysoev.ru main_port = rt->port_by_type[NXT_PROCESS_MAIN]; 357167Smax.romanov@nginx.com 358507Smax.romanov@nginx.com nxt_debug(task, "app '%V' %p start process", &app->name, app); 359343Smax.romanov@nginx.com 360343Smax.romanov@nginx.com size = app->name.length + 1 + app->conf.length; 361343Smax.romanov@nginx.com 362343Smax.romanov@nginx.com b = nxt_buf_mem_ts_alloc(task, task->thread->engine->mem_pool, size); 363343Smax.romanov@nginx.com 364343Smax.romanov@nginx.com if (nxt_slow_path(b == NULL)) { 365343Smax.romanov@nginx.com goto failed; 366167Smax.romanov@nginx.com } 367167Smax.romanov@nginx.com 368343Smax.romanov@nginx.com nxt_buf_cpystr(b, &app->name); 369343Smax.romanov@nginx.com *b->mem.free++ = '\0'; 370343Smax.romanov@nginx.com nxt_buf_cpystr(b, &app->conf); 371343Smax.romanov@nginx.com 372753Smax.romanov@nginx.com nxt_router_app_joint_use(task, app->joint, 1); 373753Smax.romanov@nginx.com 374343Smax.romanov@nginx.com stream = nxt_port_rpc_register_handler(task, port, 375343Smax.romanov@nginx.com nxt_router_app_port_ready, 376343Smax.romanov@nginx.com nxt_router_app_port_error, 377753Smax.romanov@nginx.com -1, app->joint); 378343Smax.romanov@nginx.com 379343Smax.romanov@nginx.com if (nxt_slow_path(stream == 0)) { 380753Smax.romanov@nginx.com nxt_router_app_joint_use(task, app->joint, -1); 381753Smax.romanov@nginx.com 382343Smax.romanov@nginx.com goto failed; 383343Smax.romanov@nginx.com } 384343Smax.romanov@nginx.com 385648Svbart@nginx.com ret = nxt_port_socket_write(task, main_port, NXT_PORT_MSG_START_WORKER, -1, 386648Svbart@nginx.com stream, port->id, b); 387648Svbart@nginx.com 388648Svbart@nginx.com if (nxt_slow_path(ret != NXT_OK)) { 389648Svbart@nginx.com nxt_port_rpc_cancel(task, port, stream); 390753Smax.romanov@nginx.com 391753Smax.romanov@nginx.com nxt_router_app_joint_use(task, app->joint, -1); 392753Smax.romanov@nginx.com 393648Svbart@nginx.com goto failed; 394648Svbart@nginx.com } 395343Smax.romanov@nginx.com 396753Smax.romanov@nginx.com nxt_router_app_use(task, app, -1); 397753Smax.romanov@nginx.com 398343Smax.romanov@nginx.com return; 399343Smax.romanov@nginx.com 400343Smax.romanov@nginx.com failed: 401343Smax.romanov@nginx.com 402648Svbart@nginx.com if (b != NULL) { 403648Svbart@nginx.com mp = b->data; 404648Svbart@nginx.com nxt_mp_free(mp, b); 405648Svbart@nginx.com nxt_mp_release(mp); 406648Svbart@nginx.com } 407648Svbart@nginx.com 408343Smax.romanov@nginx.com nxt_thread_mutex_lock(&app->mutex); 409343Smax.romanov@nginx.com 410507Smax.romanov@nginx.com app->pending_processes--; 411343Smax.romanov@nginx.com 412343Smax.romanov@nginx.com nxt_thread_mutex_unlock(&app->mutex); 413343Smax.romanov@nginx.com 414343Smax.romanov@nginx.com nxt_router_app_use(task, app, -1); 415167Smax.romanov@nginx.com } 416167Smax.romanov@nginx.com 417167Smax.romanov@nginx.com 418753Smax.romanov@nginx.com static void 419753Smax.romanov@nginx.com nxt_router_app_joint_use(nxt_task_t *task, nxt_app_joint_t *app_joint, int i) 420753Smax.romanov@nginx.com { 421753Smax.romanov@nginx.com app_joint->use_count += i; 422753Smax.romanov@nginx.com 423753Smax.romanov@nginx.com if (app_joint->use_count == 0) { 424753Smax.romanov@nginx.com nxt_assert(app_joint->app == NULL); 425753Smax.romanov@nginx.com 426753Smax.romanov@nginx.com nxt_free(app_joint); 427753Smax.romanov@nginx.com } 428753Smax.romanov@nginx.com } 429753Smax.romanov@nginx.com 430753Smax.romanov@nginx.com 431343Smax.romanov@nginx.com static nxt_int_t 432507Smax.romanov@nginx.com nxt_router_start_app_process(nxt_task_t *task, nxt_app_t *app) 433141Smax.romanov@nginx.com { 434343Smax.romanov@nginx.com nxt_int_t res; 435343Smax.romanov@nginx.com nxt_port_t *router_port; 436343Smax.romanov@nginx.com nxt_runtime_t *rt; 437343Smax.romanov@nginx.com 438343Smax.romanov@nginx.com rt = task->thread->runtime; 439343Smax.romanov@nginx.com router_port = rt->port_by_type[NXT_PROCESS_ROUTER]; 440343Smax.romanov@nginx.com 441343Smax.romanov@nginx.com nxt_router_app_use(task, app, 1); 442343Smax.romanov@nginx.com 443507Smax.romanov@nginx.com res = nxt_port_post(task, router_port, nxt_router_start_app_process_handler, 444343Smax.romanov@nginx.com app); 445343Smax.romanov@nginx.com 446343Smax.romanov@nginx.com if (res == NXT_OK) { 447343Smax.romanov@nginx.com return res; 448318Smax.romanov@nginx.com } 449318Smax.romanov@nginx.com 450343Smax.romanov@nginx.com nxt_thread_mutex_lock(&app->mutex); 451343Smax.romanov@nginx.com 452507Smax.romanov@nginx.com app->pending_processes--; 453343Smax.romanov@nginx.com 454343Smax.romanov@nginx.com nxt_thread_mutex_unlock(&app->mutex); 455343Smax.romanov@nginx.com 456343Smax.romanov@nginx.com nxt_router_app_use(task, app, -1); 457343Smax.romanov@nginx.com 458343Smax.romanov@nginx.com return NXT_ERROR; 459318Smax.romanov@nginx.com } 460318Smax.romanov@nginx.com 461318Smax.romanov@nginx.com 462351Smax.romanov@nginx.com nxt_inline void 4631123Smax.romanov@nginx.com nxt_request_app_link_init(nxt_task_t *task, 4641123Smax.romanov@nginx.com nxt_request_app_link_t *req_app_link, nxt_request_rpc_data_t *req_rpc_data) 465167Smax.romanov@nginx.com { 4661414Smax.romanov@nginx.com nxt_buf_t *body; 467318Smax.romanov@nginx.com nxt_event_engine_t *engine; 468351Smax.romanov@nginx.com 469318Smax.romanov@nginx.com engine = task->thread->engine; 470167Smax.romanov@nginx.com 4711123Smax.romanov@nginx.com nxt_memzero(req_app_link, sizeof(nxt_request_app_link_t)); 4721123Smax.romanov@nginx.com 4731123Smax.romanov@nginx.com req_app_link->stream = req_rpc_data->stream; 4741123Smax.romanov@nginx.com req_app_link->use_count = 1; 4751123Smax.romanov@nginx.com req_app_link->req_rpc_data = req_rpc_data; 4761123Smax.romanov@nginx.com req_rpc_data->req_app_link = req_app_link; 4771123Smax.romanov@nginx.com req_app_link->reply_port = engine->port; 4781123Smax.romanov@nginx.com req_app_link->request = req_rpc_data->request; 4791123Smax.romanov@nginx.com req_app_link->apr_action = NXT_APR_GOT_RESPONSE; 4801123Smax.romanov@nginx.com 4811123Smax.romanov@nginx.com req_app_link->work.handler = NULL; 4821123Smax.romanov@nginx.com req_app_link->work.task = &engine->task; 4831123Smax.romanov@nginx.com req_app_link->work.obj = req_app_link; 4841123Smax.romanov@nginx.com req_app_link->work.data = engine; 4851414Smax.romanov@nginx.com 4861414Smax.romanov@nginx.com body = req_rpc_data->request->body; 4871414Smax.romanov@nginx.com 4881414Smax.romanov@nginx.com if (body != NULL && nxt_buf_is_file(body)) { 4891414Smax.romanov@nginx.com req_app_link->body_fd = body->file->fd; 4901414Smax.romanov@nginx.com 4911414Smax.romanov@nginx.com body->file->fd = -1; 4921414Smax.romanov@nginx.com 4931414Smax.romanov@nginx.com } else { 4941414Smax.romanov@nginx.com req_app_link->body_fd = -1; 4951414Smax.romanov@nginx.com } 496351Smax.romanov@nginx.com } 497351Smax.romanov@nginx.com 498351Smax.romanov@nginx.com 4991123Smax.romanov@nginx.com nxt_inline nxt_request_app_link_t * 5001123Smax.romanov@nginx.com nxt_request_app_link_alloc(nxt_task_t *task, 5011123Smax.romanov@nginx.com nxt_request_app_link_t *ra_src, nxt_request_rpc_data_t *req_rpc_data) 502351Smax.romanov@nginx.com { 5031123Smax.romanov@nginx.com nxt_mp_t *mp; 5041123Smax.romanov@nginx.com nxt_request_app_link_t *req_app_link; 5051123Smax.romanov@nginx.com 5061123Smax.romanov@nginx.com if (ra_src != NULL && ra_src->mem_pool != NULL) { 507425Smax.romanov@nginx.com return ra_src; 508425Smax.romanov@nginx.com } 509425Smax.romanov@nginx.com 5101123Smax.romanov@nginx.com mp = req_rpc_data->request->mem_pool; 5111123Smax.romanov@nginx.com 5121123Smax.romanov@nginx.com req_app_link = nxt_mp_alloc(mp, sizeof(nxt_request_app_link_t)); 5131123Smax.romanov@nginx.com 5141123Smax.romanov@nginx.com if (nxt_slow_path(req_app_link == NULL)) { 5151123Smax.romanov@nginx.com 5161123Smax.romanov@nginx.com req_rpc_data->req_app_link = NULL; 5171123Smax.romanov@nginx.com 5181123Smax.romanov@nginx.com if (ra_src != NULL) { 5191123Smax.romanov@nginx.com ra_src->req_rpc_data = NULL; 5201123Smax.romanov@nginx.com } 521351Smax.romanov@nginx.com 522351Smax.romanov@nginx.com return NULL; 523351Smax.romanov@nginx.com } 524351Smax.romanov@nginx.com 525430Sigor@sysoev.ru nxt_mp_retain(mp); 526430Sigor@sysoev.ru 5271123Smax.romanov@nginx.com nxt_request_app_link_init(task, req_app_link, req_rpc_data); 5281123Smax.romanov@nginx.com 5291414Smax.romanov@nginx.com if (ra_src != NULL) { 5301414Smax.romanov@nginx.com req_app_link->body_fd = ra_src->body_fd; 5311414Smax.romanov@nginx.com } 5321414Smax.romanov@nginx.com 5331123Smax.romanov@nginx.com req_app_link->mem_pool = mp; 5341123Smax.romanov@nginx.com 5351123Smax.romanov@nginx.com return req_app_link; 536167Smax.romanov@nginx.com } 537167Smax.romanov@nginx.com 538167Smax.romanov@nginx.com 539423Smax.romanov@nginx.com nxt_inline nxt_bool_t 540423Smax.romanov@nginx.com nxt_router_msg_cancel(nxt_task_t *task, nxt_msg_info_t *msg_info, 541423Smax.romanov@nginx.com uint32_t stream) 542423Smax.romanov@nginx.com { 543423Smax.romanov@nginx.com nxt_buf_t *b, *next; 544423Smax.romanov@nginx.com nxt_bool_t cancelled; 545423Smax.romanov@nginx.com 546423Smax.romanov@nginx.com if (msg_info->buf == NULL) { 547423Smax.romanov@nginx.com return 0; 548423Smax.romanov@nginx.com } 549423Smax.romanov@nginx.com 550423Smax.romanov@nginx.com cancelled = nxt_port_mmap_tracking_cancel(task, &msg_info->tracking, 551423Smax.romanov@nginx.com stream); 552423Smax.romanov@nginx.com 553423Smax.romanov@nginx.com if (cancelled) { 554423Smax.romanov@nginx.com nxt_debug(task, "stream #%uD: cancelled by router", stream); 555423Smax.romanov@nginx.com } 556423Smax.romanov@nginx.com 557423Smax.romanov@nginx.com for (b = msg_info->buf; b != NULL; b = next) { 558423Smax.romanov@nginx.com next = b->next; 5591269Sigor@sysoev.ru b->next = NULL; 560423Smax.romanov@nginx.com 561423Smax.romanov@nginx.com b->completion_handler = msg_info->completion_handler; 562423Smax.romanov@nginx.com 563423Smax.romanov@nginx.com if (b->is_port_mmap_sent) { 564423Smax.romanov@nginx.com b->is_port_mmap_sent = cancelled == 0; 565423Smax.romanov@nginx.com b->completion_handler(task, b, b->parent); 566423Smax.romanov@nginx.com } 567423Smax.romanov@nginx.com } 568423Smax.romanov@nginx.com 569423Smax.romanov@nginx.com msg_info->buf = NULL; 570423Smax.romanov@nginx.com 571423Smax.romanov@nginx.com return cancelled; 572423Smax.romanov@nginx.com } 573423Smax.romanov@nginx.com 574423Smax.romanov@nginx.com 575167Smax.romanov@nginx.com static void 5761123Smax.romanov@nginx.com nxt_request_app_link_update_peer_handler(nxt_task_t *task, void *obj, 5771123Smax.romanov@nginx.com void *data) 5781123Smax.romanov@nginx.com { 5791123Smax.romanov@nginx.com nxt_request_app_link_t *req_app_link; 5801123Smax.romanov@nginx.com 5811123Smax.romanov@nginx.com req_app_link = obj; 5821123Smax.romanov@nginx.com 5831123Smax.romanov@nginx.com nxt_request_app_link_update_peer(task, req_app_link); 5841123Smax.romanov@nginx.com 5851123Smax.romanov@nginx.com nxt_request_app_link_use(task, req_app_link, -1); 5861123Smax.romanov@nginx.com } 587425Smax.romanov@nginx.com 588425Smax.romanov@nginx.com 589425Smax.romanov@nginx.com static void 5901123Smax.romanov@nginx.com nxt_request_app_link_update_peer(nxt_task_t *task, 5911123Smax.romanov@nginx.com nxt_request_app_link_t *req_app_link) 592167Smax.romanov@nginx.com { 5931123Smax.romanov@nginx.com nxt_event_engine_t *engine; 5941123Smax.romanov@nginx.com nxt_request_rpc_data_t *req_rpc_data; 5951123Smax.romanov@nginx.com 5961123Smax.romanov@nginx.com engine = req_app_link->work.data; 5971123Smax.romanov@nginx.com 5981123Smax.romanov@nginx.com if (task->thread->engine != engine) { 5991123Smax.romanov@nginx.com nxt_request_app_link_inc_use(req_app_link); 6001123Smax.romanov@nginx.com 6011123Smax.romanov@nginx.com req_app_link->work.handler = nxt_request_app_link_update_peer_handler; 6021123Smax.romanov@nginx.com req_app_link->work.task = &engine->task; 6031123Smax.romanov@nginx.com req_app_link->work.next = NULL; 6041123Smax.romanov@nginx.com 6051123Smax.romanov@nginx.com nxt_debug(task, "req_app_link stream #%uD post update peer to %p", 6061123Smax.romanov@nginx.com req_app_link->stream, engine); 6071123Smax.romanov@nginx.com 6081123Smax.romanov@nginx.com nxt_event_engine_post(engine, &req_app_link->work); 6091123Smax.romanov@nginx.com 6101123Smax.romanov@nginx.com return; 6111123Smax.romanov@nginx.com } 6121123Smax.romanov@nginx.com 6131123Smax.romanov@nginx.com nxt_debug(task, "req_app_link stream #%uD update peer", 6141123Smax.romanov@nginx.com req_app_link->stream); 6151123Smax.romanov@nginx.com 6161123Smax.romanov@nginx.com req_rpc_data = req_app_link->req_rpc_data; 6171123Smax.romanov@nginx.com 6181123Smax.romanov@nginx.com if (req_rpc_data != NULL && req_app_link->app_port != NULL) { 6191123Smax.romanov@nginx.com nxt_port_rpc_ex_set_peer(task, engine->port, req_rpc_data, 6201123Smax.romanov@nginx.com req_app_link->app_port->pid); 6211123Smax.romanov@nginx.com } 622425Smax.romanov@nginx.com } 623425Smax.romanov@nginx.com 624425Smax.romanov@nginx.com 625425Smax.romanov@nginx.com static void 6261123Smax.romanov@nginx.com nxt_request_app_link_release(nxt_task_t *task, 6271123Smax.romanov@nginx.com nxt_request_app_link_t *req_app_link) 628425Smax.romanov@nginx.com { 629431Sigor@sysoev.ru nxt_mp_t *mp; 6301131Smax.romanov@nginx.com nxt_http_request_t *r; 6311123Smax.romanov@nginx.com nxt_request_rpc_data_t *req_rpc_data; 6321123Smax.romanov@nginx.com 6331123Smax.romanov@nginx.com nxt_assert(task->thread->engine == req_app_link->work.data); 6341123Smax.romanov@nginx.com nxt_assert(req_app_link->use_count == 0); 6351123Smax.romanov@nginx.com 6361123Smax.romanov@nginx.com nxt_debug(task, "req_app_link stream #%uD release", req_app_link->stream); 6371123Smax.romanov@nginx.com 6381123Smax.romanov@nginx.com req_rpc_data = req_app_link->req_rpc_data; 6391123Smax.romanov@nginx.com 6401123Smax.romanov@nginx.com if (req_rpc_data != NULL) { 6411123Smax.romanov@nginx.com if (nxt_slow_path(req_app_link->err_code != 0)) { 6421123Smax.romanov@nginx.com nxt_http_request_error(task, req_rpc_data->request, 6431123Smax.romanov@nginx.com req_app_link->err_code); 644423Smax.romanov@nginx.com 645423Smax.romanov@nginx.com } else { 6461123Smax.romanov@nginx.com req_rpc_data->app_port = req_app_link->app_port; 6471123Smax.romanov@nginx.com req_rpc_data->apr_action = req_app_link->apr_action; 6481123Smax.romanov@nginx.com req_rpc_data->msg_info = req_app_link->msg_info; 6491123Smax.romanov@nginx.com 6501123Smax.romanov@nginx.com if (req_rpc_data->app->timeout != 0) { 6511131Smax.romanov@nginx.com r = req_rpc_data->request; 6521131Smax.romanov@nginx.com 6531131Smax.romanov@nginx.com r->timer.handler = nxt_router_app_timeout; 6541131Smax.romanov@nginx.com r->timer_data = req_rpc_data; 6551131Smax.romanov@nginx.com nxt_timer_add(task->thread->engine, &r->timer, 6561123Smax.romanov@nginx.com req_rpc_data->app->timeout); 657425Smax.romanov@nginx.com } 658425Smax.romanov@nginx.com 6591123Smax.romanov@nginx.com req_app_link->app_port = NULL; 6601123Smax.romanov@nginx.com req_app_link->msg_info.buf = NULL; 661423Smax.romanov@nginx.com } 662343Smax.romanov@nginx.com 6631123Smax.romanov@nginx.com req_rpc_data->req_app_link = NULL; 6641123Smax.romanov@nginx.com req_app_link->req_rpc_data = NULL; 6651123Smax.romanov@nginx.com } 6661123Smax.romanov@nginx.com 6671123Smax.romanov@nginx.com if (req_app_link->app_port != NULL) { 6681123Smax.romanov@nginx.com nxt_router_app_port_release(task, req_app_link->app_port, 6691123Smax.romanov@nginx.com req_app_link->apr_action); 6701123Smax.romanov@nginx.com 6711123Smax.romanov@nginx.com req_app_link->app_port = NULL; 6721123Smax.romanov@nginx.com } 6731123Smax.romanov@nginx.com 6741414Smax.romanov@nginx.com if (req_app_link->body_fd != -1) { 6751414Smax.romanov@nginx.com nxt_fd_close(req_app_link->body_fd); 6761414Smax.romanov@nginx.com 6771414Smax.romanov@nginx.com req_app_link->body_fd = -1; 6781414Smax.romanov@nginx.com } 6791414Smax.romanov@nginx.com 6801123Smax.romanov@nginx.com nxt_router_msg_cancel(task, &req_app_link->msg_info, req_app_link->stream); 6811123Smax.romanov@nginx.com 6821123Smax.romanov@nginx.com mp = req_app_link->mem_pool; 683430Sigor@sysoev.ru 684430Sigor@sysoev.ru if (mp != NULL) { 6851123Smax.romanov@nginx.com nxt_mp_free(mp, req_app_link); 686430Sigor@sysoev.ru nxt_mp_release(mp); 687351Smax.romanov@nginx.com } 688167Smax.romanov@nginx.com } 689167Smax.romanov@nginx.com 690167Smax.romanov@nginx.com 691425Smax.romanov@nginx.com static void 6921123Smax.romanov@nginx.com nxt_request_app_link_release_handler(nxt_task_t *task, void *obj, void *data) 693425Smax.romanov@nginx.com { 6941123Smax.romanov@nginx.com nxt_request_app_link_t *req_app_link; 6951123Smax.romanov@nginx.com 6961123Smax.romanov@nginx.com req_app_link = obj; 6971123Smax.romanov@nginx.com 6981123Smax.romanov@nginx.com nxt_assert(req_app_link->work.data == data); 6991123Smax.romanov@nginx.com 7001123Smax.romanov@nginx.com nxt_atomic_fetch_add(&req_app_link->use_count, -1); 7011123Smax.romanov@nginx.com 7021123Smax.romanov@nginx.com nxt_request_app_link_release(task, req_app_link); 703425Smax.romanov@nginx.com } 704425Smax.romanov@nginx.com 705425Smax.romanov@nginx.com 706425Smax.romanov@nginx.com static void 7071123Smax.romanov@nginx.com nxt_request_app_link_use(nxt_task_t *task, nxt_request_app_link_t *req_app_link, 7081123Smax.romanov@nginx.com int i) 709425Smax.romanov@nginx.com { 710425Smax.romanov@nginx.com int c; 711425Smax.romanov@nginx.com nxt_event_engine_t *engine; 712425Smax.romanov@nginx.com 7131123Smax.romanov@nginx.com c = nxt_atomic_fetch_add(&req_app_link->use_count, i); 714425Smax.romanov@nginx.com 715425Smax.romanov@nginx.com if (i < 0 && c == -i) { 7161123Smax.romanov@nginx.com engine = req_app_link->work.data; 717425Smax.romanov@nginx.com 718425Smax.romanov@nginx.com if (task->thread->engine == engine) { 7191123Smax.romanov@nginx.com nxt_request_app_link_release(task, req_app_link); 720425Smax.romanov@nginx.com 721425Smax.romanov@nginx.com return; 722425Smax.romanov@nginx.com } 723425Smax.romanov@nginx.com 7241123Smax.romanov@nginx.com nxt_request_app_link_inc_use(req_app_link); 7251123Smax.romanov@nginx.com 7261123Smax.romanov@nginx.com req_app_link->work.handler = nxt_request_app_link_release_handler; 7271123Smax.romanov@nginx.com req_app_link->work.task = &engine->task; 7281123Smax.romanov@nginx.com req_app_link->work.next = NULL; 7291123Smax.romanov@nginx.com 7301123Smax.romanov@nginx.com nxt_debug(task, "req_app_link stream #%uD post release to %p", 7311123Smax.romanov@nginx.com req_app_link->stream, engine); 7321123Smax.romanov@nginx.com 7331123Smax.romanov@nginx.com nxt_event_engine_post(engine, &req_app_link->work); 734425Smax.romanov@nginx.com } 735425Smax.romanov@nginx.com } 736425Smax.romanov@nginx.com 737425Smax.romanov@nginx.com 738423Smax.romanov@nginx.com nxt_inline void 7391446Smax.romanov@nginx.com nxt_request_app_link_error(nxt_task_t *task, nxt_app_t *app, 7401446Smax.romanov@nginx.com nxt_request_app_link_t *req_app_link, const char *str) 741345Smax.romanov@nginx.com { 7421123Smax.romanov@nginx.com req_app_link->app_port = NULL; 7431446Smax.romanov@nginx.com req_app_link->err_code = 500; 7441123Smax.romanov@nginx.com req_app_link->err_str = str; 7451446Smax.romanov@nginx.com 7461446Smax.romanov@nginx.com nxt_alert(task, "app \"%V\" internal error: %s on #%uD", 7471446Smax.romanov@nginx.com &app->name, str, req_app_link->stream); 748345Smax.romanov@nginx.com } 749345Smax.romanov@nginx.com 750345Smax.romanov@nginx.com 751427Smax.romanov@nginx.com nxt_inline void 7521123Smax.romanov@nginx.com nxt_request_app_link_pending(nxt_task_t *task, nxt_app_t *app, 7531123Smax.romanov@nginx.com nxt_request_app_link_t *req_app_link) 754427Smax.romanov@nginx.com { 7551123Smax.romanov@nginx.com nxt_queue_insert_tail(&req_app_link->app_port->pending_requests, 7561123Smax.romanov@nginx.com &req_app_link->link_port_pending); 7571123Smax.romanov@nginx.com nxt_queue_insert_tail(&app->pending, &req_app_link->link_app_pending); 7581123Smax.romanov@nginx.com 7591123Smax.romanov@nginx.com nxt_request_app_link_inc_use(req_app_link); 7601123Smax.romanov@nginx.com 7611123Smax.romanov@nginx.com req_app_link->res_time = nxt_thread_monotonic_time(task->thread) 7621123Smax.romanov@nginx.com + app->res_timeout; 7631123Smax.romanov@nginx.com 7641123Smax.romanov@nginx.com nxt_debug(task, "req_app_link stream #%uD enqueue to pending_requests", 7651123Smax.romanov@nginx.com req_app_link->stream); 766427Smax.romanov@nginx.com } 767427Smax.romanov@nginx.com 768427Smax.romanov@nginx.com 769425Smax.romanov@nginx.com nxt_inline nxt_bool_t 770425Smax.romanov@nginx.com nxt_queue_chk_remove(nxt_queue_link_t *lnk) 771425Smax.romanov@nginx.com { 772425Smax.romanov@nginx.com if (lnk->next != NULL) { 773425Smax.romanov@nginx.com nxt_queue_remove(lnk); 774425Smax.romanov@nginx.com 775425Smax.romanov@nginx.com lnk->next = NULL; 776425Smax.romanov@nginx.com 777425Smax.romanov@nginx.com return 1; 778425Smax.romanov@nginx.com } 779425Smax.romanov@nginx.com 780425Smax.romanov@nginx.com return 0; 781425Smax.romanov@nginx.com } 782