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; 30133Sigor@sysoev.ru } nxt_router_app_conf_t; 31133Sigor@sysoev.ru 32133Sigor@sysoev.ru 33133Sigor@sysoev.ru typedef struct { 34964Sigor@sysoev.ru nxt_str_t pass; 35964Sigor@sysoev.ru nxt_str_t application; 36115Sigor@sysoev.ru } nxt_router_listener_conf_t; 37115Sigor@sysoev.ru 38115Sigor@sysoev.ru 39774Svbart@nginx.com #if (NXT_TLS) 40774Svbart@nginx.com 41774Svbart@nginx.com typedef struct { 42774Svbart@nginx.com nxt_str_t name; 43774Svbart@nginx.com nxt_socket_conf_t *conf; 44774Svbart@nginx.com 45774Svbart@nginx.com nxt_queue_link_t link; /* for nxt_socket_conf_t.tls */ 46774Svbart@nginx.com } nxt_router_tlssock_t; 47774Svbart@nginx.com 48774Svbart@nginx.com #endif 49774Svbart@nginx.com 50774Svbart@nginx.com 51198Sigor@sysoev.ru typedef struct { 52198Sigor@sysoev.ru nxt_socket_conf_t *socket_conf; 53198Sigor@sysoev.ru nxt_router_temp_conf_t *temp_conf; 54198Sigor@sysoev.ru } nxt_socket_rpc_t; 55198Sigor@sysoev.ru 56198Sigor@sysoev.ru 57507Smax.romanov@nginx.com typedef struct { 58507Smax.romanov@nginx.com nxt_app_t *app; 59507Smax.romanov@nginx.com nxt_router_temp_conf_t *temp_conf; 60507Smax.romanov@nginx.com } nxt_app_rpc_t; 61507Smax.romanov@nginx.com 62507Smax.romanov@nginx.com 63427Smax.romanov@nginx.com struct nxt_port_select_state_s { 641123Smax.romanov@nginx.com nxt_app_t *app; 651123Smax.romanov@nginx.com nxt_request_app_link_t *req_app_link; 661123Smax.romanov@nginx.com 671123Smax.romanov@nginx.com nxt_port_t *failed_port; 681123Smax.romanov@nginx.com int failed_port_use_delta; 691123Smax.romanov@nginx.com 701123Smax.romanov@nginx.com uint8_t start_process; /* 1 bit */ 711123Smax.romanov@nginx.com nxt_request_app_link_t *shared_ra; 721123Smax.romanov@nginx.com nxt_port_t *port; 73427Smax.romanov@nginx.com }; 74427Smax.romanov@nginx.com 75427Smax.romanov@nginx.com typedef struct nxt_port_select_state_s nxt_port_select_state_t; 76427Smax.romanov@nginx.com 77662Smax.romanov@nginx.com static void nxt_router_greet_controller(nxt_task_t *task, 78662Smax.romanov@nginx.com nxt_port_t *controller_port); 79662Smax.romanov@nginx.com 80427Smax.romanov@nginx.com static void nxt_router_port_select(nxt_task_t *task, 81427Smax.romanov@nginx.com nxt_port_select_state_t *state); 82427Smax.romanov@nginx.com 83427Smax.romanov@nginx.com static nxt_int_t nxt_router_port_post_select(nxt_task_t *task, 84427Smax.romanov@nginx.com nxt_port_select_state_t *state); 85427Smax.romanov@nginx.com 86507Smax.romanov@nginx.com static nxt_int_t nxt_router_start_app_process(nxt_task_t *task, nxt_app_t *app); 871123Smax.romanov@nginx.com static void nxt_request_app_link_update_peer(nxt_task_t *task, 881123Smax.romanov@nginx.com nxt_request_app_link_t *req_app_link); 891123Smax.romanov@nginx.com 90343Smax.romanov@nginx.com 91425Smax.romanov@nginx.com nxt_inline void 921123Smax.romanov@nginx.com nxt_request_app_link_inc_use(nxt_request_app_link_t *req_app_link) 93425Smax.romanov@nginx.com { 941123Smax.romanov@nginx.com nxt_atomic_fetch_add(&req_app_link->use_count, 1); 95425Smax.romanov@nginx.com } 96425Smax.romanov@nginx.com 97425Smax.romanov@nginx.com nxt_inline void 98*1294Smax.romanov@nginx.com nxt_request_app_link_chk_use(nxt_request_app_link_t *req_app_link, int i) 99425Smax.romanov@nginx.com { 100538Svbart@nginx.com #if (NXT_DEBUG) 101425Smax.romanov@nginx.com int c; 102425Smax.romanov@nginx.com 103*1294Smax.romanov@nginx.com c = nxt_atomic_fetch_add(&req_app_link->use_count, i); 104*1294Smax.romanov@nginx.com 105*1294Smax.romanov@nginx.com nxt_assert((c + i) > 0); 106538Svbart@nginx.com #else 107*1294Smax.romanov@nginx.com (void) nxt_atomic_fetch_add(&req_app_link->use_count, i); 108538Svbart@nginx.com #endif 109425Smax.romanov@nginx.com } 110425Smax.romanov@nginx.com 1111123Smax.romanov@nginx.com static void nxt_request_app_link_use(nxt_task_t *task, 1121123Smax.romanov@nginx.com nxt_request_app_link_t *req_app_link, int i); 113425Smax.romanov@nginx.com 114139Sigor@sysoev.ru static nxt_router_temp_conf_t *nxt_router_temp_conf(nxt_task_t *task); 115198Sigor@sysoev.ru static void nxt_router_conf_apply(nxt_task_t *task, void *obj, void *data); 116198Sigor@sysoev.ru static void nxt_router_conf_ready(nxt_task_t *task, 117139Sigor@sysoev.ru nxt_router_temp_conf_t *tmcf); 118139Sigor@sysoev.ru static void nxt_router_conf_error(nxt_task_t *task, 119139Sigor@sysoev.ru nxt_router_temp_conf_t *tmcf); 120139Sigor@sysoev.ru static void nxt_router_conf_send(nxt_task_t *task, 121193Smax.romanov@nginx.com nxt_router_temp_conf_t *tmcf, nxt_port_msg_type_t type); 12253Sigor@sysoev.ru 123115Sigor@sysoev.ru static nxt_int_t nxt_router_conf_create(nxt_task_t *task, 124115Sigor@sysoev.ru nxt_router_temp_conf_t *tmcf, u_char *start, u_char *end); 1251183Svbart@nginx.com static nxt_int_t nxt_router_conf_process_static(nxt_task_t *task, 1261183Svbart@nginx.com nxt_router_conf_t *rtcf, nxt_conf_value_t *conf); 127133Sigor@sysoev.ru static nxt_app_t *nxt_router_app_find(nxt_queue_t *queue, nxt_str_t *name); 128198Sigor@sysoev.ru static void nxt_router_listen_socket_rpc_create(nxt_task_t *task, 129198Sigor@sysoev.ru nxt_router_temp_conf_t *tmcf, nxt_socket_conf_t *skcf); 130198Sigor@sysoev.ru static void nxt_router_listen_socket_ready(nxt_task_t *task, 131198Sigor@sysoev.ru nxt_port_recv_msg_t *msg, void *data); 132198Sigor@sysoev.ru static void nxt_router_listen_socket_error(nxt_task_t *task, 133198Sigor@sysoev.ru nxt_port_recv_msg_t *msg, void *data); 134774Svbart@nginx.com #if (NXT_TLS) 135774Svbart@nginx.com static void nxt_router_tls_rpc_create(nxt_task_t *task, 136774Svbart@nginx.com nxt_router_temp_conf_t *tmcf, nxt_router_tlssock_t *tls); 137774Svbart@nginx.com static void nxt_router_tls_rpc_handler(nxt_task_t *task, 138774Svbart@nginx.com nxt_port_recv_msg_t *msg, void *data); 139774Svbart@nginx.com #endif 140507Smax.romanov@nginx.com static void nxt_router_app_rpc_create(nxt_task_t *task, 141507Smax.romanov@nginx.com nxt_router_temp_conf_t *tmcf, nxt_app_t *app); 142507Smax.romanov@nginx.com static void nxt_router_app_prefork_ready(nxt_task_t *task, 143507Smax.romanov@nginx.com nxt_port_recv_msg_t *msg, void *data); 144507Smax.romanov@nginx.com static void nxt_router_app_prefork_error(nxt_task_t *task, 145507Smax.romanov@nginx.com nxt_port_recv_msg_t *msg, void *data); 146359Sigor@sysoev.ru static nxt_socket_conf_t *nxt_router_socket_conf(nxt_task_t *task, 147359Sigor@sysoev.ru nxt_router_temp_conf_t *tmcf, nxt_str_t *name); 148359Sigor@sysoev.ru static nxt_int_t nxt_router_listen_socket_find(nxt_router_temp_conf_t *tmcf, 149359Sigor@sysoev.ru nxt_socket_conf_t *nskcf, nxt_sockaddr_t *sa); 15053Sigor@sysoev.ru 15153Sigor@sysoev.ru static nxt_int_t nxt_router_engines_create(nxt_task_t *task, 15253Sigor@sysoev.ru nxt_router_t *router, nxt_router_temp_conf_t *tmcf, 15353Sigor@sysoev.ru const nxt_event_interface_t *interface); 154115Sigor@sysoev.ru static nxt_int_t nxt_router_engine_conf_create(nxt_router_temp_conf_t *tmcf, 155115Sigor@sysoev.ru nxt_router_engine_conf_t *recf); 156115Sigor@sysoev.ru static nxt_int_t nxt_router_engine_conf_update(nxt_router_temp_conf_t *tmcf, 157115Sigor@sysoev.ru nxt_router_engine_conf_t *recf); 158115Sigor@sysoev.ru static nxt_int_t nxt_router_engine_conf_delete(nxt_router_temp_conf_t *tmcf, 159115Sigor@sysoev.ru nxt_router_engine_conf_t *recf); 160154Sigor@sysoev.ru static nxt_int_t nxt_router_engine_joints_create(nxt_router_temp_conf_t *tmcf, 161154Sigor@sysoev.ru nxt_router_engine_conf_t *recf, nxt_queue_t *sockets, 162154Sigor@sysoev.ru nxt_work_handler_t handler); 163313Sigor@sysoev.ru static nxt_int_t nxt_router_engine_quit(nxt_router_temp_conf_t *tmcf, 164313Sigor@sysoev.ru nxt_router_engine_conf_t *recf); 165139Sigor@sysoev.ru static nxt_int_t nxt_router_engine_joints_delete(nxt_router_temp_conf_t *tmcf, 166139Sigor@sysoev.ru nxt_router_engine_conf_t *recf, nxt_queue_t *sockets); 16753Sigor@sysoev.ru 16853Sigor@sysoev.ru static nxt_int_t nxt_router_threads_create(nxt_task_t *task, nxt_runtime_t *rt, 16953Sigor@sysoev.ru nxt_router_temp_conf_t *tmcf); 17053Sigor@sysoev.ru static nxt_int_t nxt_router_thread_create(nxt_task_t *task, nxt_runtime_t *rt, 17153Sigor@sysoev.ru nxt_event_engine_t *engine); 172343Smax.romanov@nginx.com static void nxt_router_apps_sort(nxt_task_t *task, nxt_router_t *router, 173133Sigor@sysoev.ru nxt_router_temp_conf_t *tmcf); 17453Sigor@sysoev.ru 175315Sigor@sysoev.ru static void nxt_router_engines_post(nxt_router_t *router, 176315Sigor@sysoev.ru nxt_router_temp_conf_t *tmcf); 177315Sigor@sysoev.ru static void nxt_router_engine_post(nxt_event_engine_t *engine, 178315Sigor@sysoev.ru nxt_work_t *jobs); 17953Sigor@sysoev.ru 18053Sigor@sysoev.ru static void nxt_router_thread_start(void *data); 18153Sigor@sysoev.ru static void nxt_router_listen_socket_create(nxt_task_t *task, void *obj, 18253Sigor@sysoev.ru void *data); 18353Sigor@sysoev.ru static void nxt_router_listen_socket_update(nxt_task_t *task, void *obj, 18453Sigor@sysoev.ru void *data); 18553Sigor@sysoev.ru static void nxt_router_listen_socket_delete(nxt_task_t *task, void *obj, 18653Sigor@sysoev.ru void *data); 187313Sigor@sysoev.ru static void nxt_router_worker_thread_quit(nxt_task_t *task, void *obj, 188313Sigor@sysoev.ru void *data); 18953Sigor@sysoev.ru static void nxt_router_listen_socket_close(nxt_task_t *task, void *obj, 19053Sigor@sysoev.ru void *data); 19153Sigor@sysoev.ru static void nxt_router_thread_exit_handler(nxt_task_t *task, void *obj, 19253Sigor@sysoev.ru void *data); 193359Sigor@sysoev.ru static void nxt_router_listen_socket_release(nxt_task_t *task, 194359Sigor@sysoev.ru nxt_socket_conf_t *skcf); 19553Sigor@sysoev.ru 196630Svbart@nginx.com static void nxt_router_access_log_writer(nxt_task_t *task, 197630Svbart@nginx.com nxt_http_request_t *r, nxt_router_access_log_t *access_log); 198630Svbart@nginx.com static u_char *nxt_router_access_log_date(u_char *buf, nxt_realtime_t *now, 199630Svbart@nginx.com struct tm *tm, size_t size, const char *format); 200630Svbart@nginx.com static void nxt_router_access_log_open(nxt_task_t *task, 201630Svbart@nginx.com nxt_router_temp_conf_t *tmcf); 202630Svbart@nginx.com static void nxt_router_access_log_ready(nxt_task_t *task, 203630Svbart@nginx.com nxt_port_recv_msg_t *msg, void *data); 204630Svbart@nginx.com static void nxt_router_access_log_error(nxt_task_t *task, 205630Svbart@nginx.com nxt_port_recv_msg_t *msg, void *data); 206630Svbart@nginx.com static void nxt_router_access_log_release(nxt_task_t *task, 207630Svbart@nginx.com nxt_thread_spinlock_t *lock, nxt_router_access_log_t *access_log); 208651Svbart@nginx.com static void nxt_router_access_log_reopen_completion(nxt_task_t *task, void *obj, 209651Svbart@nginx.com void *data); 210631Svbart@nginx.com static void nxt_router_access_log_reopen_ready(nxt_task_t *task, 211631Svbart@nginx.com nxt_port_recv_msg_t *msg, void *data); 212631Svbart@nginx.com static void nxt_router_access_log_reopen_error(nxt_task_t *task, 213631Svbart@nginx.com nxt_port_recv_msg_t *msg, void *data); 214630Svbart@nginx.com 215343Smax.romanov@nginx.com static void nxt_router_app_port_ready(nxt_task_t *task, 216343Smax.romanov@nginx.com nxt_port_recv_msg_t *msg, void *data); 217343Smax.romanov@nginx.com static void nxt_router_app_port_error(nxt_task_t *task, 218343Smax.romanov@nginx.com nxt_port_recv_msg_t *msg, void *data); 219343Smax.romanov@nginx.com 220753Smax.romanov@nginx.com static void nxt_router_app_unlink(nxt_task_t *task, nxt_app_t *app); 2211123Smax.romanov@nginx.com 222343Smax.romanov@nginx.com static void nxt_router_app_port_release(nxt_task_t *task, nxt_port_t *port, 2231123Smax.romanov@nginx.com nxt_apr_action_t action); 224427Smax.romanov@nginx.com static nxt_int_t nxt_router_app_port(nxt_task_t *task, nxt_app_t *app, 2251123Smax.romanov@nginx.com nxt_request_app_link_t *req_app_link); 226141Smax.romanov@nginx.com 227425Smax.romanov@nginx.com static void nxt_router_app_prepare_request(nxt_task_t *task, 2281123Smax.romanov@nginx.com nxt_request_app_link_t *req_app_link); 2291007Salexander.borisov@nginx.com static nxt_buf_t *nxt_router_prepare_msg(nxt_task_t *task, 2301007Salexander.borisov@nginx.com nxt_http_request_t *r, nxt_port_t *port, const nxt_str_t *prefix); 231510Salexander.borisov@nginx.com 232318Smax.romanov@nginx.com static void nxt_router_app_timeout(nxt_task_t *task, void *obj, void *data); 233507Smax.romanov@nginx.com static void nxt_router_adjust_idle_timer(nxt_task_t *task, void *obj, 234507Smax.romanov@nginx.com void *data); 235507Smax.romanov@nginx.com static void nxt_router_app_idle_timeout(nxt_task_t *task, void *obj, 236507Smax.romanov@nginx.com void *data); 237753Smax.romanov@nginx.com static void nxt_router_app_joint_release_handler(nxt_task_t *task, void *obj, 238507Smax.romanov@nginx.com void *data); 239753Smax.romanov@nginx.com static void nxt_router_free_app(nxt_task_t *task, void *obj, void *data); 240431Sigor@sysoev.ru 241431Sigor@sysoev.ru static const nxt_http_request_state_t nxt_http_request_send_state; 242431Sigor@sysoev.ru static void nxt_http_request_send_body(nxt_task_t *task, void *obj, void *data); 243141Smax.romanov@nginx.com 244753Smax.romanov@nginx.com static void nxt_router_app_joint_use(nxt_task_t *task, 245753Smax.romanov@nginx.com nxt_app_joint_t *app_joint, int i); 246753Smax.romanov@nginx.com 2471007Salexander.borisov@nginx.com static nxt_int_t nxt_router_http_request_done(nxt_task_t *task, 2481007Salexander.borisov@nginx.com nxt_http_request_t *r); 2491007Salexander.borisov@nginx.com static void nxt_router_http_request_release(nxt_task_t *task, void *obj, 2501007Salexander.borisov@nginx.com void *data); 2511007Salexander.borisov@nginx.com 2521149Smax.romanov@nginx.com extern const nxt_http_request_state_t nxt_http_websocket; 2531131Smax.romanov@nginx.com 254119Smax.romanov@nginx.com static nxt_router_t *nxt_router; 25520Sigor@sysoev.ru 256743Smax.romanov@nginx.com static const nxt_str_t http_prefix = nxt_string("HTTP_"); 257743Smax.romanov@nginx.com static const nxt_str_t empty_prefix = nxt_string(""); 258743Smax.romanov@nginx.com 259743Smax.romanov@nginx.com static const nxt_str_t *nxt_app_msg_prefix[] = { 260804Svbart@nginx.com &empty_prefix, 261743Smax.romanov@nginx.com &http_prefix, 262743Smax.romanov@nginx.com &http_prefix, 263743Smax.romanov@nginx.com &http_prefix, 264743Smax.romanov@nginx.com &http_prefix, 265977Smax.romanov@gmail.com &empty_prefix, 266216Sigor@sysoev.ru }; 267216Sigor@sysoev.ru 268216Sigor@sysoev.ru 269662Smax.romanov@nginx.com nxt_port_handlers_t nxt_router_process_port_handlers = { 270662Smax.romanov@nginx.com .quit = nxt_worker_process_quit_handler, 271662Smax.romanov@nginx.com .new_port = nxt_router_new_port_handler, 272662Smax.romanov@nginx.com .change_file = nxt_port_change_log_file_handler, 273662Smax.romanov@nginx.com .mmap = nxt_port_mmap_handler, 274662Smax.romanov@nginx.com .data = nxt_router_conf_data_handler, 275662Smax.romanov@nginx.com .remove_pid = nxt_router_remove_pid_handler, 276662Smax.romanov@nginx.com .access_log = nxt_router_access_log_reopen_handler, 277662Smax.romanov@nginx.com .rpc_ready = nxt_port_rpc_handler, 278662Smax.romanov@nginx.com .rpc_error = nxt_port_rpc_handler, 279662Smax.romanov@nginx.com }; 280662Smax.romanov@nginx.com 281662Smax.romanov@nginx.com 28220Sigor@sysoev.ru nxt_int_t 283141Smax.romanov@nginx.com nxt_router_start(nxt_task_t *task, void *data) 28420Sigor@sysoev.ru { 285141Smax.romanov@nginx.com nxt_int_t ret; 286662Smax.romanov@nginx.com nxt_port_t *controller_port; 287141Smax.romanov@nginx.com nxt_router_t *router; 288141Smax.romanov@nginx.com nxt_runtime_t *rt; 289141Smax.romanov@nginx.com 290141Smax.romanov@nginx.com rt = task->thread->runtime; 29153Sigor@sysoev.ru 292771Sigor@sysoev.ru #if (NXT_TLS) 293771Sigor@sysoev.ru rt->tls = nxt_service_get(rt->services, "SSL/TLS", "OpenSSL"); 294771Sigor@sysoev.ru if (nxt_slow_path(rt->tls == NULL)) { 295771Sigor@sysoev.ru return NXT_ERROR; 296771Sigor@sysoev.ru } 297771Sigor@sysoev.ru 298771Sigor@sysoev.ru ret = rt->tls->library_init(task); 299771Sigor@sysoev.ru if (nxt_slow_path(ret != NXT_OK)) { 300771Sigor@sysoev.ru return ret; 301771Sigor@sysoev.ru } 302771Sigor@sysoev.ru #endif 303771Sigor@sysoev.ru 304431Sigor@sysoev.ru ret = nxt_http_init(task, rt); 30588Smax.romanov@nginx.com if (nxt_slow_path(ret != NXT_OK)) { 30688Smax.romanov@nginx.com return ret; 30788Smax.romanov@nginx.com } 30888Smax.romanov@nginx.com 30953Sigor@sysoev.ru router = nxt_zalloc(sizeof(nxt_router_t)); 31053Sigor@sysoev.ru if (nxt_slow_path(router == NULL)) { 31153Sigor@sysoev.ru return NXT_ERROR; 31253Sigor@sysoev.ru } 31353Sigor@sysoev.ru 31453Sigor@sysoev.ru nxt_queue_init(&router->engines); 31553Sigor@sysoev.ru nxt_queue_init(&router->sockets); 316133Sigor@sysoev.ru nxt_queue_init(&router->apps); 31753Sigor@sysoev.ru 318119Smax.romanov@nginx.com nxt_router = router; 319119Smax.romanov@nginx.com 320662Smax.romanov@nginx.com controller_port = rt->port_by_type[NXT_PROCESS_CONTROLLER]; 321662Smax.romanov@nginx.com if (controller_port != NULL) { 322662Smax.romanov@nginx.com nxt_router_greet_controller(task, controller_port); 323662Smax.romanov@nginx.com } 324662Smax.romanov@nginx.com 325115Sigor@sysoev.ru return NXT_OK; 326115Sigor@sysoev.ru } 327115Sigor@sysoev.ru 328115Sigor@sysoev.ru 329343Smax.romanov@nginx.com static void 330662Smax.romanov@nginx.com nxt_router_greet_controller(nxt_task_t *task, nxt_port_t *controller_port) 331662Smax.romanov@nginx.com { 332662Smax.romanov@nginx.com nxt_port_socket_write(task, controller_port, NXT_PORT_MSG_PROCESS_READY, 333662Smax.romanov@nginx.com -1, 0, 0, NULL); 334662Smax.romanov@nginx.com } 335662Smax.romanov@nginx.com 336662Smax.romanov@nginx.com 337662Smax.romanov@nginx.com static void 338507Smax.romanov@nginx.com nxt_router_start_app_process_handler(nxt_task_t *task, nxt_port_t *port, 339507Smax.romanov@nginx.com void *data) 340167Smax.romanov@nginx.com { 341343Smax.romanov@nginx.com size_t size; 342343Smax.romanov@nginx.com uint32_t stream; 343430Sigor@sysoev.ru nxt_mp_t *mp; 344648Svbart@nginx.com nxt_int_t ret; 345343Smax.romanov@nginx.com nxt_app_t *app; 346343Smax.romanov@nginx.com nxt_buf_t *b; 347343Smax.romanov@nginx.com nxt_port_t *main_port; 348343Smax.romanov@nginx.com nxt_runtime_t *rt; 349343Smax.romanov@nginx.com 350343Smax.romanov@nginx.com app = data; 351167Smax.romanov@nginx.com 352167Smax.romanov@nginx.com rt = task->thread->runtime; 353240Sigor@sysoev.ru main_port = rt->port_by_type[NXT_PROCESS_MAIN]; 354167Smax.romanov@nginx.com 355507Smax.romanov@nginx.com nxt_debug(task, "app '%V' %p start process", &app->name, app); 356343Smax.romanov@nginx.com 357343Smax.romanov@nginx.com size = app->name.length + 1 + app->conf.length; 358343Smax.romanov@nginx.com 359343Smax.romanov@nginx.com b = nxt_buf_mem_ts_alloc(task, task->thread->engine->mem_pool, size); 360343Smax.romanov@nginx.com 361343Smax.romanov@nginx.com if (nxt_slow_path(b == NULL)) { 362343Smax.romanov@nginx.com goto failed; 363167Smax.romanov@nginx.com } 364167Smax.romanov@nginx.com 365343Smax.romanov@nginx.com nxt_buf_cpystr(b, &app->name); 366343Smax.romanov@nginx.com *b->mem.free++ = '\0'; 367343Smax.romanov@nginx.com nxt_buf_cpystr(b, &app->conf); 368343Smax.romanov@nginx.com 369753Smax.romanov@nginx.com nxt_router_app_joint_use(task, app->joint, 1); 370753Smax.romanov@nginx.com 371343Smax.romanov@nginx.com stream = nxt_port_rpc_register_handler(task, port, 372343Smax.romanov@nginx.com nxt_router_app_port_ready, 373343Smax.romanov@nginx.com nxt_router_app_port_error, 374753Smax.romanov@nginx.com -1, app->joint); 375343Smax.romanov@nginx.com 376343Smax.romanov@nginx.com if (nxt_slow_path(stream == 0)) { 377753Smax.romanov@nginx.com nxt_router_app_joint_use(task, app->joint, -1); 378753Smax.romanov@nginx.com 379343Smax.romanov@nginx.com goto failed; 380343Smax.romanov@nginx.com } 381343Smax.romanov@nginx.com 382648Svbart@nginx.com ret = nxt_port_socket_write(task, main_port, NXT_PORT_MSG_START_WORKER, -1, 383648Svbart@nginx.com stream, port->id, b); 384648Svbart@nginx.com 385648Svbart@nginx.com if (nxt_slow_path(ret != NXT_OK)) { 386648Svbart@nginx.com nxt_port_rpc_cancel(task, port, stream); 387753Smax.romanov@nginx.com 388753Smax.romanov@nginx.com nxt_router_app_joint_use(task, app->joint, -1); 389753Smax.romanov@nginx.com 390648Svbart@nginx.com goto failed; 391648Svbart@nginx.com } 392343Smax.romanov@nginx.com 393753Smax.romanov@nginx.com nxt_router_app_use(task, app, -1); 394753Smax.romanov@nginx.com 395343Smax.romanov@nginx.com return; 396343Smax.romanov@nginx.com 397343Smax.romanov@nginx.com failed: 398343Smax.romanov@nginx.com 399648Svbart@nginx.com if (b != NULL) { 400648Svbart@nginx.com mp = b->data; 401648Svbart@nginx.com nxt_mp_free(mp, b); 402648Svbart@nginx.com nxt_mp_release(mp); 403648Svbart@nginx.com } 404648Svbart@nginx.com 405343Smax.romanov@nginx.com nxt_thread_mutex_lock(&app->mutex); 406343Smax.romanov@nginx.com 407507Smax.romanov@nginx.com app->pending_processes--; 408343Smax.romanov@nginx.com 409343Smax.romanov@nginx.com nxt_thread_mutex_unlock(&app->mutex); 410343Smax.romanov@nginx.com 411343Smax.romanov@nginx.com nxt_router_app_use(task, app, -1); 412167Smax.romanov@nginx.com } 413167Smax.romanov@nginx.com 414167Smax.romanov@nginx.com 415753Smax.romanov@nginx.com static void 416753Smax.romanov@nginx.com nxt_router_app_joint_use(nxt_task_t *task, nxt_app_joint_t *app_joint, int i) 417753Smax.romanov@nginx.com { 418753Smax.romanov@nginx.com app_joint->use_count += i; 419753Smax.romanov@nginx.com 420753Smax.romanov@nginx.com if (app_joint->use_count == 0) { 421753Smax.romanov@nginx.com nxt_assert(app_joint->app == NULL); 422753Smax.romanov@nginx.com 423753Smax.romanov@nginx.com nxt_free(app_joint); 424753Smax.romanov@nginx.com } 425753Smax.romanov@nginx.com } 426753Smax.romanov@nginx.com 427753Smax.romanov@nginx.com 428343Smax.romanov@nginx.com static nxt_int_t 429507Smax.romanov@nginx.com nxt_router_start_app_process(nxt_task_t *task, nxt_app_t *app) 430141Smax.romanov@nginx.com { 431343Smax.romanov@nginx.com nxt_int_t res; 432343Smax.romanov@nginx.com nxt_port_t *router_port; 433343Smax.romanov@nginx.com nxt_runtime_t *rt; 434343Smax.romanov@nginx.com 435343Smax.romanov@nginx.com rt = task->thread->runtime; 436343Smax.romanov@nginx.com router_port = rt->port_by_type[NXT_PROCESS_ROUTER]; 437343Smax.romanov@nginx.com 438343Smax.romanov@nginx.com nxt_router_app_use(task, app, 1); 439343Smax.romanov@nginx.com 440507Smax.romanov@nginx.com res = nxt_port_post(task, router_port, nxt_router_start_app_process_handler, 441343Smax.romanov@nginx.com app); 442343Smax.romanov@nginx.com 443343Smax.romanov@nginx.com if (res == NXT_OK) { 444343Smax.romanov@nginx.com return res; 445318Smax.romanov@nginx.com } 446318Smax.romanov@nginx.com 447343Smax.romanov@nginx.com nxt_thread_mutex_lock(&app->mutex); 448343Smax.romanov@nginx.com 449507Smax.romanov@nginx.com app->pending_processes--; 450343Smax.romanov@nginx.com 451343Smax.romanov@nginx.com nxt_thread_mutex_unlock(&app->mutex); 452343Smax.romanov@nginx.com 453343Smax.romanov@nginx.com nxt_router_app_use(task, app, -1); 454343Smax.romanov@nginx.com 455343Smax.romanov@nginx.com return NXT_ERROR; 456318Smax.romanov@nginx.com } 457318Smax.romanov@nginx.com 458318Smax.romanov@nginx.com 459351Smax.romanov@nginx.com nxt_inline void 4601123Smax.romanov@nginx.com nxt_request_app_link_init(nxt_task_t *task, 4611123Smax.romanov@nginx.com nxt_request_app_link_t *req_app_link, nxt_request_rpc_data_t *req_rpc_data) 462167Smax.romanov@nginx.com { 463318Smax.romanov@nginx.com nxt_event_engine_t *engine; 464351Smax.romanov@nginx.com 465318Smax.romanov@nginx.com engine = task->thread->engine; 466167Smax.romanov@nginx.com 4671123Smax.romanov@nginx.com nxt_memzero(req_app_link, sizeof(nxt_request_app_link_t)); 4681123Smax.romanov@nginx.com 4691123Smax.romanov@nginx.com req_app_link->stream = req_rpc_data->stream; 4701123Smax.romanov@nginx.com req_app_link->use_count = 1; 4711123Smax.romanov@nginx.com req_app_link->req_rpc_data = req_rpc_data; 4721123Smax.romanov@nginx.com req_rpc_data->req_app_link = req_app_link; 4731123Smax.romanov@nginx.com req_app_link->reply_port = engine->port; 4741123Smax.romanov@nginx.com req_app_link->request = req_rpc_data->request; 4751123Smax.romanov@nginx.com req_app_link->apr_action = NXT_APR_GOT_RESPONSE; 4761123Smax.romanov@nginx.com 4771123Smax.romanov@nginx.com req_app_link->work.handler = NULL; 4781123Smax.romanov@nginx.com req_app_link->work.task = &engine->task; 4791123Smax.romanov@nginx.com req_app_link->work.obj = req_app_link; 4801123Smax.romanov@nginx.com req_app_link->work.data = engine; 481351Smax.romanov@nginx.com } 482351Smax.romanov@nginx.com 483351Smax.romanov@nginx.com 4841123Smax.romanov@nginx.com nxt_inline nxt_request_app_link_t * 4851123Smax.romanov@nginx.com nxt_request_app_link_alloc(nxt_task_t *task, 4861123Smax.romanov@nginx.com nxt_request_app_link_t *ra_src, nxt_request_rpc_data_t *req_rpc_data) 487351Smax.romanov@nginx.com { 4881123Smax.romanov@nginx.com nxt_mp_t *mp; 4891123Smax.romanov@nginx.com nxt_request_app_link_t *req_app_link; 4901123Smax.romanov@nginx.com 4911123Smax.romanov@nginx.com if (ra_src != NULL && ra_src->mem_pool != NULL) { 492425Smax.romanov@nginx.com return ra_src; 493425Smax.romanov@nginx.com } 494425Smax.romanov@nginx.com 4951123Smax.romanov@nginx.com mp = req_rpc_data->request->mem_pool; 4961123Smax.romanov@nginx.com 4971123Smax.romanov@nginx.com req_app_link = nxt_mp_alloc(mp, sizeof(nxt_request_app_link_t)); 4981123Smax.romanov@nginx.com 4991123Smax.romanov@nginx.com if (nxt_slow_path(req_app_link == NULL)) { 5001123Smax.romanov@nginx.com 5011123Smax.romanov@nginx.com req_rpc_data->req_app_link = NULL; 5021123Smax.romanov@nginx.com 5031123Smax.romanov@nginx.com if (ra_src != NULL) { 5041123Smax.romanov@nginx.com ra_src->req_rpc_data = NULL; 5051123Smax.romanov@nginx.com } 506351Smax.romanov@nginx.com 507351Smax.romanov@nginx.com return NULL; 508351Smax.romanov@nginx.com } 509351Smax.romanov@nginx.com 510430Sigor@sysoev.ru nxt_mp_retain(mp); 511430Sigor@sysoev.ru 5121123Smax.romanov@nginx.com nxt_request_app_link_init(task, req_app_link, req_rpc_data); 5131123Smax.romanov@nginx.com 5141123Smax.romanov@nginx.com req_app_link->mem_pool = mp; 5151123Smax.romanov@nginx.com 5161123Smax.romanov@nginx.com return req_app_link; 517167Smax.romanov@nginx.com } 518167Smax.romanov@nginx.com 519167Smax.romanov@nginx.com 520423Smax.romanov@nginx.com nxt_inline nxt_bool_t 521423Smax.romanov@nginx.com nxt_router_msg_cancel(nxt_task_t *task, nxt_msg_info_t *msg_info, 522423Smax.romanov@nginx.com uint32_t stream) 523423Smax.romanov@nginx.com { 524423Smax.romanov@nginx.com nxt_buf_t *b, *next; 525423Smax.romanov@nginx.com nxt_bool_t cancelled; 526423Smax.romanov@nginx.com 527423Smax.romanov@nginx.com if (msg_info->buf == NULL) { 528423Smax.romanov@nginx.com return 0; 529423Smax.romanov@nginx.com } 530423Smax.romanov@nginx.com 531423Smax.romanov@nginx.com cancelled = nxt_port_mmap_tracking_cancel(task, &msg_info->tracking, 532423Smax.romanov@nginx.com stream); 533423Smax.romanov@nginx.com 534423Smax.romanov@nginx.com if (cancelled) { 535423Smax.romanov@nginx.com nxt_debug(task, "stream #%uD: cancelled by router", stream); 536423Smax.romanov@nginx.com } 537423Smax.romanov@nginx.com 538423Smax.romanov@nginx.com for (b = msg_info->buf; b != NULL; b = next) { 539423Smax.romanov@nginx.com next = b->next; 5401269Sigor@sysoev.ru b->next = NULL; 541423Smax.romanov@nginx.com 542423Smax.romanov@nginx.com b->completion_handler = msg_info->completion_handler; 543423Smax.romanov@nginx.com 544423Smax.romanov@nginx.com if (b->is_port_mmap_sent) { 545423Smax.romanov@nginx.com b->is_port_mmap_sent = cancelled == 0; 546423Smax.romanov@nginx.com b->completion_handler(task, b, b->parent); 547423Smax.romanov@nginx.com } 548423Smax.romanov@nginx.com } 549423Smax.romanov@nginx.com 550423Smax.romanov@nginx.com msg_info->buf = NULL; 551423Smax.romanov@nginx.com 552423Smax.romanov@nginx.com return cancelled; 553423Smax.romanov@nginx.com } 554423Smax.romanov@nginx.com 555423Smax.romanov@nginx.com 556167Smax.romanov@nginx.com static void 5571123Smax.romanov@nginx.com nxt_request_app_link_update_peer_handler(nxt_task_t *task, void *obj, 5581123Smax.romanov@nginx.com void *data) 5591123Smax.romanov@nginx.com { 5601123Smax.romanov@nginx.com nxt_request_app_link_t *req_app_link; 5611123Smax.romanov@nginx.com 5621123Smax.romanov@nginx.com req_app_link = obj; 5631123Smax.romanov@nginx.com 5641123Smax.romanov@nginx.com nxt_request_app_link_update_peer(task, req_app_link); 5651123Smax.romanov@nginx.com 5661123Smax.romanov@nginx.com nxt_request_app_link_use(task, req_app_link, -1); 5671123Smax.romanov@nginx.com } 568425Smax.romanov@nginx.com 569425Smax.romanov@nginx.com 570425Smax.romanov@nginx.com static void 5711123Smax.romanov@nginx.com nxt_request_app_link_update_peer(nxt_task_t *task, 5721123Smax.romanov@nginx.com nxt_request_app_link_t *req_app_link) 573167Smax.romanov@nginx.com { 5741123Smax.romanov@nginx.com nxt_event_engine_t *engine; 5751123Smax.romanov@nginx.com nxt_request_rpc_data_t *req_rpc_data; 5761123Smax.romanov@nginx.com 5771123Smax.romanov@nginx.com engine = req_app_link->work.data; 5781123Smax.romanov@nginx.com 5791123Smax.romanov@nginx.com if (task->thread->engine != engine) { 5801123Smax.romanov@nginx.com nxt_request_app_link_inc_use(req_app_link); 5811123Smax.romanov@nginx.com 5821123Smax.romanov@nginx.com req_app_link->work.handler = nxt_request_app_link_update_peer_handler; 5831123Smax.romanov@nginx.com req_app_link->work.task = &engine->task; 5841123Smax.romanov@nginx.com req_app_link->work.next = NULL; 5851123Smax.romanov@nginx.com 5861123Smax.romanov@nginx.com nxt_debug(task, "req_app_link stream #%uD post update peer to %p", 5871123Smax.romanov@nginx.com req_app_link->stream, engine); 5881123Smax.romanov@nginx.com 5891123Smax.romanov@nginx.com nxt_event_engine_post(engine, &req_app_link->work); 5901123Smax.romanov@nginx.com 5911123Smax.romanov@nginx.com return; 5921123Smax.romanov@nginx.com } 5931123Smax.romanov@nginx.com 5941123Smax.romanov@nginx.com nxt_debug(task, "req_app_link stream #%uD update peer", 5951123Smax.romanov@nginx.com req_app_link->stream); 5961123Smax.romanov@nginx.com 5971123Smax.romanov@nginx.com req_rpc_data = req_app_link->req_rpc_data; 5981123Smax.romanov@nginx.com 5991123Smax.romanov@nginx.com if (req_rpc_data != NULL && req_app_link->app_port != NULL) { 6001123Smax.romanov@nginx.com nxt_port_rpc_ex_set_peer(task, engine->port, req_rpc_data, 6011123Smax.romanov@nginx.com req_app_link->app_port->pid); 6021123Smax.romanov@nginx.com } 603425Smax.romanov@nginx.com } 604425Smax.romanov@nginx.com 605425Smax.romanov@nginx.com 606425Smax.romanov@nginx.com static void 6071123Smax.romanov@nginx.com nxt_request_app_link_release(nxt_task_t *task, 6081123Smax.romanov@nginx.com nxt_request_app_link_t *req_app_link) 609425Smax.romanov@nginx.com { 610431Sigor@sysoev.ru nxt_mp_t *mp; 6111131Smax.romanov@nginx.com nxt_http_request_t *r; 6121123Smax.romanov@nginx.com nxt_request_rpc_data_t *req_rpc_data; 6131123Smax.romanov@nginx.com 6141123Smax.romanov@nginx.com nxt_assert(task->thread->engine == req_app_link->work.data); 6151123Smax.romanov@nginx.com nxt_assert(req_app_link->use_count == 0); 6161123Smax.romanov@nginx.com 6171123Smax.romanov@nginx.com nxt_debug(task, "req_app_link stream #%uD release", req_app_link->stream); 6181123Smax.romanov@nginx.com 6191123Smax.romanov@nginx.com req_rpc_data = req_app_link->req_rpc_data; 6201123Smax.romanov@nginx.com 6211123Smax.romanov@nginx.com if (req_rpc_data != NULL) { 6221123Smax.romanov@nginx.com if (nxt_slow_path(req_app_link->err_code != 0)) { 6231123Smax.romanov@nginx.com nxt_http_request_error(task, req_rpc_data->request, 6241123Smax.romanov@nginx.com req_app_link->err_code); 625423Smax.romanov@nginx.com 626423Smax.romanov@nginx.com } else { 6271123Smax.romanov@nginx.com req_rpc_data->app_port = req_app_link->app_port; 6281123Smax.romanov@nginx.com req_rpc_data->apr_action = req_app_link->apr_action; 6291123Smax.romanov@nginx.com req_rpc_data->msg_info = req_app_link->msg_info; 6301123Smax.romanov@nginx.com 6311123Smax.romanov@nginx.com if (req_rpc_data->app->timeout != 0) { 6321131Smax.romanov@nginx.com r = req_rpc_data->request; 6331131Smax.romanov@nginx.com 6341131Smax.romanov@nginx.com r->timer.handler = nxt_router_app_timeout; 6351131Smax.romanov@nginx.com r->timer_data = req_rpc_data; 6361131Smax.romanov@nginx.com nxt_timer_add(task->thread->engine, &r->timer, 6371123Smax.romanov@nginx.com req_rpc_data->app->timeout); 638425Smax.romanov@nginx.com } 639425Smax.romanov@nginx.com 6401123Smax.romanov@nginx.com req_app_link->app_port = NULL; 6411123Smax.romanov@nginx.com req_app_link->msg_info.buf = NULL; 642423Smax.romanov@nginx.com } 643343Smax.romanov@nginx.com 6441123Smax.romanov@nginx.com req_rpc_data->req_app_link = NULL; 6451123Smax.romanov@nginx.com req_app_link->req_rpc_data = NULL; 6461123Smax.romanov@nginx.com } 6471123Smax.romanov@nginx.com 6481123Smax.romanov@nginx.com if (req_app_link->app_port != NULL) { 6491123Smax.romanov@nginx.com nxt_router_app_port_release(task, req_app_link->app_port, 6501123Smax.romanov@nginx.com req_app_link->apr_action); 6511123Smax.romanov@nginx.com 6521123Smax.romanov@nginx.com req_app_link->app_port = NULL; 6531123Smax.romanov@nginx.com } 6541123Smax.romanov@nginx.com 6551123Smax.romanov@nginx.com nxt_router_msg_cancel(task, &req_app_link->msg_info, req_app_link->stream); 6561123Smax.romanov@nginx.com 6571123Smax.romanov@nginx.com mp = req_app_link->mem_pool; 658430Sigor@sysoev.ru 659430Sigor@sysoev.ru if (mp != NULL) { 6601123Smax.romanov@nginx.com nxt_mp_free(mp, req_app_link); 661430Sigor@sysoev.ru nxt_mp_release(mp); 662351Smax.romanov@nginx.com } 663167Smax.romanov@nginx.com } 664167Smax.romanov@nginx.com 665167Smax.romanov@nginx.com 666425Smax.romanov@nginx.com static void 6671123Smax.romanov@nginx.com nxt_request_app_link_release_handler(nxt_task_t *task, void *obj, void *data) 668425Smax.romanov@nginx.com { 6691123Smax.romanov@nginx.com nxt_request_app_link_t *req_app_link; 6701123Smax.romanov@nginx.com 6711123Smax.romanov@nginx.com req_app_link = obj; 6721123Smax.romanov@nginx.com 6731123Smax.romanov@nginx.com nxt_assert(req_app_link->work.data == data); 6741123Smax.romanov@nginx.com 6751123Smax.romanov@nginx.com nxt_atomic_fetch_add(&req_app_link->use_count, -1); 6761123Smax.romanov@nginx.com 6771123Smax.romanov@nginx.com nxt_request_app_link_release(task, req_app_link); 678425Smax.romanov@nginx.com } 679425Smax.romanov@nginx.com 680425Smax.romanov@nginx.com 681425Smax.romanov@nginx.com static void 6821123Smax.romanov@nginx.com nxt_request_app_link_use(nxt_task_t *task, nxt_request_app_link_t *req_app_link, 6831123Smax.romanov@nginx.com int i) 684425Smax.romanov@nginx.com { 685425Smax.romanov@nginx.com int c; 686425Smax.romanov@nginx.com nxt_event_engine_t *engine; 687425Smax.romanov@nginx.com 6881123Smax.romanov@nginx.com c = nxt_atomic_fetch_add(&req_app_link->use_count, i); 689425Smax.romanov@nginx.com 690425Smax.romanov@nginx.com if (i < 0 && c == -i) { 6911123Smax.romanov@nginx.com engine = req_app_link->work.data; 692425Smax.romanov@nginx.com 693425Smax.romanov@nginx.com if (task->thread->engine == engine) { 6941123Smax.romanov@nginx.com nxt_request_app_link_release(task, req_app_link); 695425Smax.romanov@nginx.com 696425Smax.romanov@nginx.com return; 697425Smax.romanov@nginx.com } 698425Smax.romanov@nginx.com 6991123Smax.romanov@nginx.com nxt_request_app_link_inc_use(req_app_link); 7001123Smax.romanov@nginx.com 7011123Smax.romanov@nginx.com req_app_link->work.handler = nxt_request_app_link_release_handler; 7021123Smax.romanov@nginx.com req_app_link->work.task = &engine->task; 7031123Smax.romanov@nginx.com req_app_link->work.next = NULL; 7041123Smax.romanov@nginx.com 7051123Smax.romanov@nginx.com nxt_debug(task, "req_app_link stream #%uD post release to %p", 7061123Smax.romanov@nginx.com req_app_link->stream, engine); 7071123Smax.romanov@nginx.com 7081123Smax.romanov@nginx.com nxt_event_engine_post(engine, &req_app_link->work); 709425Smax.romanov@nginx.com } 710425Smax.romanov@nginx.com } 711425Smax.romanov@nginx.com 712425Smax.romanov@nginx.com 713423Smax.romanov@nginx.com nxt_inline void 7141123Smax.romanov@nginx.com nxt_request_app_link_error(nxt_request_app_link_t *req_app_link, int code, 7151123Smax.romanov@nginx.com const char *str) 716345Smax.romanov@nginx.com { 7171123Smax.romanov@nginx.com req_app_link->app_port = NULL; 7181123Smax.romanov@nginx.com req_app_link->err_code = code; 7191123Smax.romanov@nginx.com req_app_link->err_str = str; 720345Smax.romanov@nginx.com } 721345Smax.romanov@nginx.com 722345Smax.romanov@nginx.com 723427Smax.romanov@nginx.com nxt_inline void 7241123Smax.romanov@nginx.com nxt_request_app_link_pending(nxt_task_t *task, nxt_app_t *app, 7251123Smax.romanov@nginx.com nxt_request_app_link_t *req_app_link) 726427Smax.romanov@nginx.com { 7271123Smax.romanov@nginx.com nxt_queue_insert_tail(&req_app_link->app_port->pending_requests, 7281123Smax.romanov@nginx.com &req_app_link->link_port_pending); 7291123Smax.romanov@nginx.com nxt_queue_insert_tail(&app->pending, &req_app_link->link_app_pending); 7301123Smax.romanov@nginx.com 7311123Smax.romanov@nginx.com nxt_request_app_link_inc_use(req_app_link); 7321123Smax.romanov@nginx.com 7331123Smax.romanov@nginx.com req_app_link->res_time = nxt_thread_monotonic_time(task->thread) 7341123Smax.romanov@nginx.com + app->res_timeout; 7351123Smax.romanov@nginx.com 7361123Smax.romanov@nginx.com nxt_debug(task, "req_app_link stream #%uD enqueue to pending_requests", 7371123Smax.romanov@nginx.com req_app_link->stream); 738427Smax.romanov@nginx.com } 739427Smax.romanov@nginx.com 740427Smax.romanov@nginx.com 741425Smax.romanov@nginx.com nxt_inline nxt_bool_t 742425Smax.romanov@nginx.com nxt_queue_chk_remove(nxt_queue_link_t *lnk) 743425Smax.romanov@nginx.com { 744425Smax.romanov@nginx.com if (lnk->next != NULL) { 745425Smax.romanov@nginx.com nxt_queue_remove(lnk); 746425Smax.romanov@nginx.com 747425Smax.romanov@nginx.com lnk->next = NULL; 748425Smax.romanov@nginx.com 749425Smax.romanov@nginx.com return 1; 750425Smax.romanov@nginx.com } 751425Smax.romanov@nginx.com 752425Smax.romanov@nginx.com return 0; 753425Smax.romanov@nginx.com } 754425Smax.romanov@nginx.com 755425Smax.romanov@nginx.com 756343Smax.romanov@nginx.com nxt_inline void 7571123Smax.romanov@nginx.com nxt_request_rpc_data_unlink(nxt_task_t *task, 7581123Smax.romanov@nginx.com nxt_request_rpc_data_t *req_rpc_data) 759343Smax.romanov@nginx.com { 7601123Smax.romanov@nginx.com int ra_use_delta; 7611123Smax.romanov@nginx.com nxt_request_app_link_t *req_app_link; 7621123Smax.romanov@nginx.com 7631123Smax.romanov@nginx.com if (req_rpc_data->app_port != NULL) { 7641123Smax.romanov@nginx.com nxt_router_app_port_release(task, req_rpc_data->app_port, 7651123Smax.romanov@nginx.com req_rpc_data->apr_action); 7661123Smax.romanov@nginx.com 7671123Smax.romanov@nginx.com req_rpc_data->app_port = NULL; 7681123Smax.romanov@nginx.com } 7691123Smax.romanov@nginx.com 7701123Smax.romanov@nginx.com nxt_router_msg_cancel(task, &req_rpc_data->msg_info, req_rpc_data->stream); 7711123Smax.romanov@nginx.com 7721123Smax.romanov@nginx.com req_app_link = req_rpc_data->req_app_link; 7731123Smax.romanov@nginx.com if (req_app_link != NULL) { 7741123Smax.romanov@nginx.com req_rpc_data->req_app_link = NULL; 7751123Smax.romanov@nginx.com req_app_link->req_rpc_data = NULL; 776343Smax.romanov@nginx.com 777425Smax.romanov@nginx.com ra_use_delta = 0; 778425Smax.romanov@nginx.com 7791123Smax.romanov@nginx.com nxt_thread_mutex_lock(&req_rpc_data->app->mutex); 7801123Smax.romanov@nginx.com 7811123Smax.romanov@nginx.com if (req_app_link->link_app_requests.next == NULL 7821123Smax.romanov@nginx.com && req_app_link->link_port_pending.next == NULL 7831131Smax.romanov@nginx.com && req_app_link->link_app_pending.next == NULL 7841131Smax.romanov@nginx.com && req_app_link->link_port_websockets.next == NULL) 785425Smax.romanov@nginx.com { 7861123Smax.romanov@nginx.com req_app_link = NULL; 787343Smax.romanov@nginx.com 788