111Sigor@sysoev.ru 211Sigor@sysoev.ru /* 311Sigor@sysoev.ru * Copyright (C) Igor Sysoev 411Sigor@sysoev.ru * Copyright (C) NGINX, Inc. 511Sigor@sysoev.ru */ 611Sigor@sysoev.ru 711Sigor@sysoev.ru #include <nxt_main.h> 820Sigor@sysoev.ru #include <nxt_runtime.h> 911Sigor@sysoev.ru #include <nxt_port.h> 10163Smax.romanov@nginx.com #include <nxt_router.h> 1111Sigor@sysoev.ru 1211Sigor@sysoev.ru 1314Sigor@sysoev.ru static void nxt_port_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg); 1411Sigor@sysoev.ru 15163Smax.romanov@nginx.com static nxt_atomic_uint_t nxt_port_last_id = 1; 16163Smax.romanov@nginx.com 17163Smax.romanov@nginx.com 18197Smax.romanov@nginx.com static void 19197Smax.romanov@nginx.com nxt_port_mp_cleanup(nxt_task_t *task, void *obj, void *data) 20197Smax.romanov@nginx.com { 21197Smax.romanov@nginx.com nxt_mp_t *mp; 22197Smax.romanov@nginx.com nxt_port_t *port; 23197Smax.romanov@nginx.com 24197Smax.romanov@nginx.com port = obj; 25197Smax.romanov@nginx.com mp = data; 26197Smax.romanov@nginx.com 27197Smax.romanov@nginx.com nxt_assert(port->pair[0] == -1); 28197Smax.romanov@nginx.com nxt_assert(port->pair[1] == -1); 29197Smax.romanov@nginx.com 30343Smax.romanov@nginx.com nxt_assert(port->use_count == 0); 31197Smax.romanov@nginx.com nxt_assert(port->app_link.next == NULL); 32507Smax.romanov@nginx.com nxt_assert(port->idle_link.next == NULL); 33197Smax.romanov@nginx.com 34197Smax.romanov@nginx.com nxt_assert(nxt_queue_is_empty(&port->messages)); 35197Smax.romanov@nginx.com nxt_assert(nxt_lvlhsh_is_empty(&port->rpc_streams)); 36197Smax.romanov@nginx.com nxt_assert(nxt_lvlhsh_is_empty(&port->rpc_peers)); 37197Smax.romanov@nginx.com 38343Smax.romanov@nginx.com nxt_thread_mutex_destroy(&port->write_mutex); 39343Smax.romanov@nginx.com 40197Smax.romanov@nginx.com nxt_mp_free(mp, port); 41197Smax.romanov@nginx.com } 42197Smax.romanov@nginx.com 43197Smax.romanov@nginx.com 44163Smax.romanov@nginx.com nxt_port_t * 45197Smax.romanov@nginx.com nxt_port_new(nxt_task_t *task, nxt_port_id_t id, nxt_pid_t pid, 46197Smax.romanov@nginx.com nxt_process_type_t type) 47163Smax.romanov@nginx.com { 48163Smax.romanov@nginx.com nxt_mp_t *mp; 49163Smax.romanov@nginx.com nxt_port_t *port; 50163Smax.romanov@nginx.com 51163Smax.romanov@nginx.com mp = nxt_mp_create(1024, 128, 256, 32); 52163Smax.romanov@nginx.com 53163Smax.romanov@nginx.com if (nxt_slow_path(mp == NULL)) { 54163Smax.romanov@nginx.com return NULL; 55163Smax.romanov@nginx.com } 56163Smax.romanov@nginx.com 57163Smax.romanov@nginx.com port = nxt_mp_zalloc(mp, sizeof(nxt_port_t)); 58163Smax.romanov@nginx.com 59163Smax.romanov@nginx.com if (nxt_fast_path(port != NULL)) { 60163Smax.romanov@nginx.com port->id = id; 61163Smax.romanov@nginx.com port->pid = pid; 62163Smax.romanov@nginx.com port->type = type; 63163Smax.romanov@nginx.com port->mem_pool = mp; 64343Smax.romanov@nginx.com port->use_count = 1; 65163Smax.romanov@nginx.com 66197Smax.romanov@nginx.com nxt_mp_cleanup(mp, nxt_port_mp_cleanup, task, port, mp); 67197Smax.romanov@nginx.com 68163Smax.romanov@nginx.com nxt_queue_init(&port->messages); 69343Smax.romanov@nginx.com nxt_thread_mutex_create(&port->write_mutex); 70425Smax.romanov@nginx.com nxt_queue_init(&port->pending_requests); 71163Smax.romanov@nginx.com 72163Smax.romanov@nginx.com } else { 73163Smax.romanov@nginx.com nxt_mp_destroy(mp); 74163Smax.romanov@nginx.com } 75163Smax.romanov@nginx.com 76167Smax.romanov@nginx.com nxt_thread_log_debug("port %p %d:%d new, type %d", port, pid, id, type); 77167Smax.romanov@nginx.com 78163Smax.romanov@nginx.com return port; 79163Smax.romanov@nginx.com } 80163Smax.romanov@nginx.com 81163Smax.romanov@nginx.com 82343Smax.romanov@nginx.com void 83343Smax.romanov@nginx.com nxt_port_close(nxt_task_t *task, nxt_port_t *port) 84163Smax.romanov@nginx.com { 85343Smax.romanov@nginx.com nxt_debug(task, "port %p %d:%d close, type %d", port, port->pid, 86343Smax.romanov@nginx.com port->id, port->type); 87167Smax.romanov@nginx.com 88163Smax.romanov@nginx.com if (port->pair[0] != -1) { 89163Smax.romanov@nginx.com nxt_fd_close(port->pair[0]); 90163Smax.romanov@nginx.com port->pair[0] = -1; 91163Smax.romanov@nginx.com } 92163Smax.romanov@nginx.com 93163Smax.romanov@nginx.com if (port->pair[1] != -1) { 94163Smax.romanov@nginx.com nxt_fd_close(port->pair[1]); 95163Smax.romanov@nginx.com port->pair[1] = -1; 96343Smax.romanov@nginx.com 97343Smax.romanov@nginx.com if (port->app != NULL) { 98343Smax.romanov@nginx.com nxt_router_app_port_close(task, port); 99343Smax.romanov@nginx.com } 100163Smax.romanov@nginx.com } 101343Smax.romanov@nginx.com } 102343Smax.romanov@nginx.com 103163Smax.romanov@nginx.com 104343Smax.romanov@nginx.com static void 105343Smax.romanov@nginx.com nxt_port_release(nxt_task_t *task, nxt_port_t *port) 106343Smax.romanov@nginx.com { 107343Smax.romanov@nginx.com nxt_debug(task, "port %p %d:%d release, type %d", port, port->pid, 108343Smax.romanov@nginx.com port->id, port->type); 109343Smax.romanov@nginx.com 110343Smax.romanov@nginx.com if (port->app != NULL) { 111343Smax.romanov@nginx.com nxt_router_app_use(task, port->app, -1); 112343Smax.romanov@nginx.com 113343Smax.romanov@nginx.com port->app = NULL; 114163Smax.romanov@nginx.com } 115163Smax.romanov@nginx.com 116163Smax.romanov@nginx.com if (port->link.next != NULL) { 117349Smax.romanov@nginx.com nxt_assert(port->process != NULL); 118349Smax.romanov@nginx.com 119163Smax.romanov@nginx.com nxt_process_port_remove(port); 120349Smax.romanov@nginx.com 121349Smax.romanov@nginx.com nxt_process_use(task, port->process, -1); 122163Smax.romanov@nginx.com } 123163Smax.romanov@nginx.com 124430Sigor@sysoev.ru nxt_mp_release(port->mem_pool); 125163Smax.romanov@nginx.com } 126163Smax.romanov@nginx.com 127141Smax.romanov@nginx.com 128141Smax.romanov@nginx.com nxt_port_id_t 129141Smax.romanov@nginx.com nxt_port_get_next_id() 130141Smax.romanov@nginx.com { 131141Smax.romanov@nginx.com return nxt_atomic_fetch_add(&nxt_port_last_id, 1); 132141Smax.romanov@nginx.com } 133141Smax.romanov@nginx.com 13411Sigor@sysoev.ru 13511Sigor@sysoev.ru void 136141Smax.romanov@nginx.com nxt_port_reset_next_id() 137141Smax.romanov@nginx.com { 138141Smax.romanov@nginx.com nxt_port_last_id = 1; 139141Smax.romanov@nginx.com } 140141Smax.romanov@nginx.com 141141Smax.romanov@nginx.com 142141Smax.romanov@nginx.com void 143141Smax.romanov@nginx.com nxt_port_enable(nxt_task_t *task, nxt_port_t *port, 144320Smax.romanov@nginx.com nxt_port_handlers_t *handlers) 14511Sigor@sysoev.ru { 14614Sigor@sysoev.ru port->pid = nxt_pid; 14714Sigor@sysoev.ru port->handler = nxt_port_handler; 148320Smax.romanov@nginx.com port->data = (nxt_port_handler_t *) (handlers); 14911Sigor@sysoev.ru 15077Smax.romanov@nginx.com nxt_port_read_enable(task, port); 15111Sigor@sysoev.ru } 15211Sigor@sysoev.ru 15311Sigor@sysoev.ru 15411Sigor@sysoev.ru static void 15514Sigor@sysoev.ru nxt_port_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg) 15611Sigor@sysoev.ru { 15714Sigor@sysoev.ru nxt_port_handler_t *handlers; 15811Sigor@sysoev.ru 159125Smax.romanov@nginx.com if (nxt_fast_path(msg->port_msg.type < NXT_PORT_MSG_MAX)) { 16011Sigor@sysoev.ru 16111Sigor@sysoev.ru nxt_debug(task, "port %d: message type:%uD", 16242Smax.romanov@nginx.com msg->port->socket.fd, msg->port_msg.type); 16311Sigor@sysoev.ru 16411Sigor@sysoev.ru handlers = msg->port->data; 16542Smax.romanov@nginx.com handlers[msg->port_msg.type](task, msg); 16611Sigor@sysoev.ru 16711Sigor@sysoev.ru return; 16811Sigor@sysoev.ru } 16911Sigor@sysoev.ru 170*564Svbart@nginx.com nxt_alert(task, "port %d: unknown message type:%uD", 171*564Svbart@nginx.com msg->port->socket.fd, msg->port_msg.type); 17211Sigor@sysoev.ru } 17311Sigor@sysoev.ru 17411Sigor@sysoev.ru 17511Sigor@sysoev.ru void 17614Sigor@sysoev.ru nxt_port_quit_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg) 17711Sigor@sysoev.ru { 17820Sigor@sysoev.ru nxt_runtime_quit(task); 17911Sigor@sysoev.ru } 18011Sigor@sysoev.ru 18111Sigor@sysoev.ru 182366Smax.romanov@nginx.com nxt_inline void 18320Sigor@sysoev.ru nxt_port_send_new_port(nxt_task_t *task, nxt_runtime_t *rt, 184141Smax.romanov@nginx.com nxt_port_t *new_port, uint32_t stream) 18511Sigor@sysoev.ru { 186141Smax.romanov@nginx.com nxt_port_t *port; 18781Smax.romanov@nginx.com nxt_process_t *process; 18811Sigor@sysoev.ru 189141Smax.romanov@nginx.com nxt_debug(task, "new port %d for process %PI", 190141Smax.romanov@nginx.com new_port->pair[1], new_port->pid); 19111Sigor@sysoev.ru 192277Sigor@sysoev.ru nxt_runtime_process_each(rt, process) { 193277Sigor@sysoev.ru 19442Smax.romanov@nginx.com if (process->pid == new_port->pid || process->pid == nxt_pid) { 19511Sigor@sysoev.ru continue; 19611Sigor@sysoev.ru } 19711Sigor@sysoev.ru 198141Smax.romanov@nginx.com port = nxt_process_port_first(process); 199141Smax.romanov@nginx.com 200366Smax.romanov@nginx.com if (nxt_proc_conn_martix[port->type][new_port->type]) { 201141Smax.romanov@nginx.com (void) nxt_port_send_port(task, port, new_port, stream); 202141Smax.romanov@nginx.com } 203277Sigor@sysoev.ru 204277Sigor@sysoev.ru } nxt_runtime_process_loop; 20511Sigor@sysoev.ru } 20611Sigor@sysoev.ru 20711Sigor@sysoev.ru 20881Smax.romanov@nginx.com nxt_int_t 209141Smax.romanov@nginx.com nxt_port_send_port(nxt_task_t *task, nxt_port_t *port, nxt_port_t *new_port, 210141Smax.romanov@nginx.com uint32_t stream) 21181Smax.romanov@nginx.com { 21281Smax.romanov@nginx.com nxt_buf_t *b; 21381Smax.romanov@nginx.com nxt_port_msg_new_port_t *msg; 21481Smax.romanov@nginx.com 215342Smax.romanov@nginx.com b = nxt_buf_mem_ts_alloc(task, task->thread->engine->mem_pool, 216342Smax.romanov@nginx.com sizeof(nxt_port_data_t)); 21781Smax.romanov@nginx.com if (nxt_slow_path(b == NULL)) { 21881Smax.romanov@nginx.com return NXT_ERROR; 21981Smax.romanov@nginx.com } 22081Smax.romanov@nginx.com 22181Smax.romanov@nginx.com nxt_debug(task, "send port %FD to process %PI", 22281Smax.romanov@nginx.com new_port->pair[1], port->pid); 22381Smax.romanov@nginx.com 22481Smax.romanov@nginx.com b->mem.free += sizeof(nxt_port_msg_new_port_t); 22581Smax.romanov@nginx.com msg = (nxt_port_msg_new_port_t *) b->mem.pos; 22681Smax.romanov@nginx.com 22781Smax.romanov@nginx.com msg->id = new_port->id; 22881Smax.romanov@nginx.com msg->pid = new_port->pid; 22981Smax.romanov@nginx.com msg->max_size = port->max_size; 23081Smax.romanov@nginx.com msg->max_share = port->max_share; 23181Smax.romanov@nginx.com msg->type = new_port->type; 23281Smax.romanov@nginx.com 23381Smax.romanov@nginx.com return nxt_port_socket_write(task, port, NXT_PORT_MSG_NEW_PORT, 234141Smax.romanov@nginx.com new_port->pair[1], stream, 0, b); 23581Smax.romanov@nginx.com } 23681Smax.romanov@nginx.com 23781Smax.romanov@nginx.com 23811Sigor@sysoev.ru void 23914Sigor@sysoev.ru nxt_port_new_port_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg) 24011Sigor@sysoev.ru { 24111Sigor@sysoev.ru nxt_port_t *port; 24220Sigor@sysoev.ru nxt_process_t *process; 24320Sigor@sysoev.ru nxt_runtime_t *rt; 24414Sigor@sysoev.ru nxt_port_msg_new_port_t *new_port_msg; 24511Sigor@sysoev.ru 24620Sigor@sysoev.ru rt = task->thread->runtime; 24711Sigor@sysoev.ru 24842Smax.romanov@nginx.com new_port_msg = (nxt_port_msg_new_port_t *) msg->buf->mem.pos; 24942Smax.romanov@nginx.com 250352Smax.romanov@nginx.com /* TODO check b size and make plain */ 251352Smax.romanov@nginx.com 252141Smax.romanov@nginx.com nxt_debug(task, "new port %d received for process %PI:%d", 253141Smax.romanov@nginx.com msg->fd, new_port_msg->pid, new_port_msg->id); 254141Smax.romanov@nginx.com 255141Smax.romanov@nginx.com port = nxt_runtime_port_find(rt, new_port_msg->pid, new_port_msg->id); 256141Smax.romanov@nginx.com if (port != NULL) { 257141Smax.romanov@nginx.com nxt_debug(task, "port %PI:%d already exists", new_port_msg->pid, 258141Smax.romanov@nginx.com new_port_msg->id); 259141Smax.romanov@nginx.com 260141Smax.romanov@nginx.com nxt_fd_close(msg->fd); 261141Smax.romanov@nginx.com msg->fd = -1; 262141Smax.romanov@nginx.com return; 263141Smax.romanov@nginx.com } 264141Smax.romanov@nginx.com 26542Smax.romanov@nginx.com process = nxt_runtime_process_get(rt, new_port_msg->pid); 26620Sigor@sysoev.ru if (nxt_slow_path(process == NULL)) { 26720Sigor@sysoev.ru return; 26820Sigor@sysoev.ru } 26920Sigor@sysoev.ru 270197Smax.romanov@nginx.com port = nxt_port_new(task, new_port_msg->id, new_port_msg->pid, 271163Smax.romanov@nginx.com new_port_msg->type); 27211Sigor@sysoev.ru if (nxt_slow_path(port == NULL)) { 273349Smax.romanov@nginx.com nxt_process_use(task, process, -1); 27411Sigor@sysoev.ru return; 27511Sigor@sysoev.ru } 27611Sigor@sysoev.ru 277164Smax.romanov@nginx.com nxt_process_port_add(task, process, port); 27814Sigor@sysoev.ru 279349Smax.romanov@nginx.com nxt_process_use(task, process, -1); 280349Smax.romanov@nginx.com 28114Sigor@sysoev.ru port->pair[0] = -1; 28211Sigor@sysoev.ru port->pair[1] = msg->fd; 28314Sigor@sysoev.ru port->max_size = new_port_msg->max_size; 28414Sigor@sysoev.ru port->max_share = new_port_msg->max_share; 28511Sigor@sysoev.ru 28614Sigor@sysoev.ru port->socket.task = task; 28714Sigor@sysoev.ru 288343Smax.romanov@nginx.com nxt_runtime_port_add(task, port); 289343Smax.romanov@nginx.com 290343Smax.romanov@nginx.com nxt_port_use(task, port, -1); 29142Smax.romanov@nginx.com 29211Sigor@sysoev.ru nxt_port_write_enable(task, port); 293141Smax.romanov@nginx.com 294347Smax.romanov@nginx.com msg->u.new_port = port; 295141Smax.romanov@nginx.com } 296141Smax.romanov@nginx.com 297141Smax.romanov@nginx.com 298141Smax.romanov@nginx.com void 299320Smax.romanov@nginx.com nxt_port_process_ready_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg) 300141Smax.romanov@nginx.com { 301141Smax.romanov@nginx.com nxt_port_t *port; 302141Smax.romanov@nginx.com nxt_process_t *process; 303141Smax.romanov@nginx.com nxt_runtime_t *rt; 304141Smax.romanov@nginx.com 305141Smax.romanov@nginx.com rt = task->thread->runtime; 306141Smax.romanov@nginx.com 307240Sigor@sysoev.ru nxt_assert(nxt_runtime_is_main(rt)); 308196Smax.romanov@nginx.com 309349Smax.romanov@nginx.com process = nxt_runtime_process_find(rt, msg->port_msg.pid); 310141Smax.romanov@nginx.com if (nxt_slow_path(process == NULL)) { 311141Smax.romanov@nginx.com return; 312141Smax.romanov@nginx.com } 313141Smax.romanov@nginx.com 314141Smax.romanov@nginx.com process->ready = 1; 315141Smax.romanov@nginx.com 316551Smax.romanov@nginx.com nxt_assert(!nxt_queue_is_empty(&process->ports)); 317382Smax.romanov@nginx.com 318141Smax.romanov@nginx.com port = nxt_process_port_first(process); 319141Smax.romanov@nginx.com 320141Smax.romanov@nginx.com nxt_debug(task, "process %PI ready", msg->port_msg.pid); 321141Smax.romanov@nginx.com 322196Smax.romanov@nginx.com nxt_port_send_new_port(task, rt, port, msg->port_msg.stream); 32311Sigor@sysoev.ru } 32411Sigor@sysoev.ru 32511Sigor@sysoev.ru 32611Sigor@sysoev.ru void 32742Smax.romanov@nginx.com nxt_port_mmap_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg) 32842Smax.romanov@nginx.com { 32942Smax.romanov@nginx.com nxt_runtime_t *rt; 33042Smax.romanov@nginx.com nxt_process_t *process; 33142Smax.romanov@nginx.com 33242Smax.romanov@nginx.com rt = task->thread->runtime; 33342Smax.romanov@nginx.com 33442Smax.romanov@nginx.com if (nxt_slow_path(msg->fd == -1)) { 33542Smax.romanov@nginx.com nxt_log(task, NXT_LOG_WARN, "invalid fd passed with mmap message"); 33642Smax.romanov@nginx.com 33742Smax.romanov@nginx.com return; 33842Smax.romanov@nginx.com } 33942Smax.romanov@nginx.com 340196Smax.romanov@nginx.com process = nxt_runtime_process_find(rt, msg->port_msg.pid); 34142Smax.romanov@nginx.com if (nxt_slow_path(process == NULL)) { 34242Smax.romanov@nginx.com nxt_log(task, NXT_LOG_WARN, "failed to get process #%PI", 34342Smax.romanov@nginx.com msg->port_msg.pid); 34442Smax.romanov@nginx.com 34542Smax.romanov@nginx.com goto fail_close; 34642Smax.romanov@nginx.com } 34742Smax.romanov@nginx.com 34842Smax.romanov@nginx.com nxt_port_incoming_port_mmap(task, process, msg->fd); 34942Smax.romanov@nginx.com 35042Smax.romanov@nginx.com fail_close: 35142Smax.romanov@nginx.com 352382Smax.romanov@nginx.com nxt_fd_close(msg->fd); 35342Smax.romanov@nginx.com } 35442Smax.romanov@nginx.com 35542Smax.romanov@nginx.com 35642Smax.romanov@nginx.com void 35720Sigor@sysoev.ru nxt_port_change_log_file(nxt_task_t *task, nxt_runtime_t *rt, nxt_uint_t slot, 35820Sigor@sysoev.ru nxt_fd_t fd) 35911Sigor@sysoev.ru { 36020Sigor@sysoev.ru nxt_buf_t *b; 36120Sigor@sysoev.ru nxt_port_t *port; 36220Sigor@sysoev.ru nxt_process_t *process; 36311Sigor@sysoev.ru 36414Sigor@sysoev.ru nxt_debug(task, "change log file #%ui fd:%FD", slot, fd); 36511Sigor@sysoev.ru 366277Sigor@sysoev.ru nxt_runtime_process_each(rt, process) { 367277Sigor@sysoev.ru 36842Smax.romanov@nginx.com if (nxt_pid == process->pid) { 36942Smax.romanov@nginx.com continue; 37042Smax.romanov@nginx.com } 37111Sigor@sysoev.ru 37242Smax.romanov@nginx.com port = nxt_process_port_first(process); 37311Sigor@sysoev.ru 374342Smax.romanov@nginx.com b = nxt_buf_mem_ts_alloc(task, task->thread->engine->mem_pool, 375342Smax.romanov@nginx.com sizeof(nxt_port_data_t)); 37611Sigor@sysoev.ru if (nxt_slow_path(b == NULL)) { 37711Sigor@sysoev.ru continue; 37811Sigor@sysoev.ru } 37911Sigor@sysoev.ru 38011Sigor@sysoev.ru *(nxt_uint_t *) b->mem.pos = slot; 38111Sigor@sysoev.ru b->mem.free += sizeof(nxt_uint_t); 38211Sigor@sysoev.ru 38320Sigor@sysoev.ru (void) nxt_port_socket_write(task, port, NXT_PORT_MSG_CHANGE_FILE, 38442Smax.romanov@nginx.com fd, 0, 0, b); 385277Sigor@sysoev.ru 386277Sigor@sysoev.ru } nxt_runtime_process_loop; 38711Sigor@sysoev.ru } 38811Sigor@sysoev.ru 38911Sigor@sysoev.ru 39011Sigor@sysoev.ru void 39114Sigor@sysoev.ru nxt_port_change_log_file_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg) 39211Sigor@sysoev.ru { 39320Sigor@sysoev.ru nxt_buf_t *b; 39420Sigor@sysoev.ru nxt_uint_t slot; 39520Sigor@sysoev.ru nxt_file_t *log_file; 39620Sigor@sysoev.ru nxt_runtime_t *rt; 39711Sigor@sysoev.ru 39820Sigor@sysoev.ru rt = task->thread->runtime; 39911Sigor@sysoev.ru 40011Sigor@sysoev.ru b = msg->buf; 40111Sigor@sysoev.ru slot = *(nxt_uint_t *) b->mem.pos; 40211Sigor@sysoev.ru 40320Sigor@sysoev.ru log_file = nxt_list_elt(rt->log_files, slot); 40411Sigor@sysoev.ru 40511Sigor@sysoev.ru nxt_debug(task, "change log file %FD:%FD", msg->fd, log_file->fd); 40611Sigor@sysoev.ru 40711Sigor@sysoev.ru /* 40811Sigor@sysoev.ru * The old log file descriptor must be closed at the moment when no 40911Sigor@sysoev.ru * other threads use it. dup2() allows to use the old file descriptor 41011Sigor@sysoev.ru * for new log file. This change is performed atomically in the kernel. 41111Sigor@sysoev.ru */ 41211Sigor@sysoev.ru if (nxt_file_redirect(log_file, msg->fd) == NXT_OK) { 41311Sigor@sysoev.ru if (slot == 0) { 41411Sigor@sysoev.ru (void) nxt_file_stderr(log_file); 41511Sigor@sysoev.ru } 41611Sigor@sysoev.ru } 41711Sigor@sysoev.ru } 41811Sigor@sysoev.ru 41911Sigor@sysoev.ru 42011Sigor@sysoev.ru void 42114Sigor@sysoev.ru nxt_port_data_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg) 42211Sigor@sysoev.ru { 42342Smax.romanov@nginx.com size_t dump_size; 42411Sigor@sysoev.ru nxt_buf_t *b; 42511Sigor@sysoev.ru 42611Sigor@sysoev.ru b = msg->buf; 42742Smax.romanov@nginx.com dump_size = b->mem.free - b->mem.pos; 42811Sigor@sysoev.ru 42942Smax.romanov@nginx.com if (dump_size > 300) { 43042Smax.romanov@nginx.com dump_size = 300; 43142Smax.romanov@nginx.com } 43242Smax.romanov@nginx.com 43342Smax.romanov@nginx.com nxt_debug(task, "data: %*s", dump_size, b->mem.pos); 43411Sigor@sysoev.ru } 43511Sigor@sysoev.ru 43611Sigor@sysoev.ru 43711Sigor@sysoev.ru void 438125Smax.romanov@nginx.com nxt_port_remove_pid_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg) 439125Smax.romanov@nginx.com { 440192Smax.romanov@nginx.com nxt_buf_t *buf; 441125Smax.romanov@nginx.com nxt_pid_t pid; 442125Smax.romanov@nginx.com nxt_runtime_t *rt; 443125Smax.romanov@nginx.com nxt_process_t *process; 444125Smax.romanov@nginx.com 445192Smax.romanov@nginx.com buf = msg->buf; 446192Smax.romanov@nginx.com 447192Smax.romanov@nginx.com nxt_assert(nxt_buf_used_size(buf) == sizeof(pid)); 448192Smax.romanov@nginx.com 449192Smax.romanov@nginx.com nxt_memcpy(&pid, buf->mem.pos, sizeof(pid)); 450192Smax.romanov@nginx.com 451347Smax.romanov@nginx.com msg->u.removed_pid = pid; 452347Smax.romanov@nginx.com 453196Smax.romanov@nginx.com nxt_debug(task, "port remove pid %PI handler", pid); 454196Smax.romanov@nginx.com 455125Smax.romanov@nginx.com rt = task->thread->runtime; 456125Smax.romanov@nginx.com 457190Smax.romanov@nginx.com nxt_port_rpc_remove_peer(task, msg->port, pid); 458190Smax.romanov@nginx.com 459125Smax.romanov@nginx.com process = nxt_runtime_process_find(rt, pid); 460125Smax.romanov@nginx.com 461125Smax.romanov@nginx.com if (process) { 462349Smax.romanov@nginx.com nxt_process_close_ports(task, process); 463125Smax.romanov@nginx.com } 464125Smax.romanov@nginx.com } 465125Smax.romanov@nginx.com 466125Smax.romanov@nginx.com 467125Smax.romanov@nginx.com void 46814Sigor@sysoev.ru nxt_port_empty_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg) 46911Sigor@sysoev.ru { 47011Sigor@sysoev.ru nxt_debug(task, "port empty handler"); 47111Sigor@sysoev.ru } 472343Smax.romanov@nginx.com 473343Smax.romanov@nginx.com 474343Smax.romanov@nginx.com typedef struct { 475343Smax.romanov@nginx.com nxt_work_t work; 476343Smax.romanov@nginx.com nxt_port_t *port; 477343Smax.romanov@nginx.com nxt_port_post_handler_t handler; 478343Smax.romanov@nginx.com } nxt_port_work_t; 479343Smax.romanov@nginx.com 480343Smax.romanov@nginx.com 481343Smax.romanov@nginx.com static void 482343Smax.romanov@nginx.com nxt_port_post_handler(nxt_task_t *task, void *obj, void *data) 483343Smax.romanov@nginx.com { 484343Smax.romanov@nginx.com nxt_port_t *port; 485343Smax.romanov@nginx.com nxt_port_work_t *pw; 486343Smax.romanov@nginx.com nxt_port_post_handler_t handler; 487343Smax.romanov@nginx.com 488343Smax.romanov@nginx.com pw = obj; 489343Smax.romanov@nginx.com port = pw->port; 490343Smax.romanov@nginx.com handler = pw->handler; 491343Smax.romanov@nginx.com 492343Smax.romanov@nginx.com nxt_free(pw); 493343Smax.romanov@nginx.com 494343Smax.romanov@nginx.com handler(task, port, data); 495343Smax.romanov@nginx.com 496343Smax.romanov@nginx.com nxt_port_use(task, port, -1); 497343Smax.romanov@nginx.com } 498343Smax.romanov@nginx.com 499343Smax.romanov@nginx.com 500343Smax.romanov@nginx.com nxt_int_t 501343Smax.romanov@nginx.com nxt_port_post(nxt_task_t *task, nxt_port_t *port, 502343Smax.romanov@nginx.com nxt_port_post_handler_t handler, void *data) 503343Smax.romanov@nginx.com { 504343Smax.romanov@nginx.com nxt_port_work_t *pw; 505343Smax.romanov@nginx.com 506343Smax.romanov@nginx.com if (task->thread->engine == port->engine) { 507343Smax.romanov@nginx.com handler(task, port, data); 508343Smax.romanov@nginx.com 509343Smax.romanov@nginx.com return NXT_OK; 510343Smax.romanov@nginx.com } 511343Smax.romanov@nginx.com 512343Smax.romanov@nginx.com pw = nxt_zalloc(sizeof(nxt_port_work_t)); 513343Smax.romanov@nginx.com 514343Smax.romanov@nginx.com if (nxt_slow_path(pw == NULL)) { 515343Smax.romanov@nginx.com return NXT_ERROR; 516343Smax.romanov@nginx.com } 517343Smax.romanov@nginx.com 518343Smax.romanov@nginx.com nxt_atomic_fetch_add(&port->use_count, 1); 519343Smax.romanov@nginx.com 520343Smax.romanov@nginx.com pw->work.handler = nxt_port_post_handler; 521343Smax.romanov@nginx.com pw->work.task = &port->engine->task; 522343Smax.romanov@nginx.com pw->work.obj = pw; 523343Smax.romanov@nginx.com pw->work.data = data; 524343Smax.romanov@nginx.com 525343Smax.romanov@nginx.com pw->port = port; 526343Smax.romanov@nginx.com pw->handler = handler; 527343Smax.romanov@nginx.com 528343Smax.romanov@nginx.com nxt_event_engine_post(port->engine, &pw->work); 529343Smax.romanov@nginx.com 530343Smax.romanov@nginx.com return NXT_OK; 531343Smax.romanov@nginx.com } 532343Smax.romanov@nginx.com 533343Smax.romanov@nginx.com 534343Smax.romanov@nginx.com static void 535343Smax.romanov@nginx.com nxt_port_release_handler(nxt_task_t *task, nxt_port_t *port, void *data) 536343Smax.romanov@nginx.com { 537343Smax.romanov@nginx.com /* no op */ 538343Smax.romanov@nginx.com } 539343Smax.romanov@nginx.com 540343Smax.romanov@nginx.com 541343Smax.romanov@nginx.com void 542343Smax.romanov@nginx.com nxt_port_use(nxt_task_t *task, nxt_port_t *port, int i) 543343Smax.romanov@nginx.com { 544343Smax.romanov@nginx.com int c; 545343Smax.romanov@nginx.com 546343Smax.romanov@nginx.com c = nxt_atomic_fetch_add(&port->use_count, i); 547343Smax.romanov@nginx.com 548343Smax.romanov@nginx.com if (i < 0 && c == -i) { 549343Smax.romanov@nginx.com 550343Smax.romanov@nginx.com if (task->thread->engine == port->engine) { 551343Smax.romanov@nginx.com nxt_port_release(task, port); 552343Smax.romanov@nginx.com 553343Smax.romanov@nginx.com return; 554343Smax.romanov@nginx.com } 555343Smax.romanov@nginx.com 556343Smax.romanov@nginx.com nxt_port_post(task, port, nxt_port_release_handler, NULL); 557343Smax.romanov@nginx.com } 558343Smax.romanov@nginx.com } 559