175Smax.romanov@nginx.com 275Smax.romanov@nginx.com /* 375Smax.romanov@nginx.com * Copyright (C) Max Romanov 475Smax.romanov@nginx.com * Copyright (C) NGINX, Inc. 575Smax.romanov@nginx.com */ 675Smax.romanov@nginx.com 775Smax.romanov@nginx.com #include <nxt_port_hash.h> 875Smax.romanov@nginx.com 975Smax.romanov@nginx.com 1075Smax.romanov@nginx.com // Explicitly using 32 bit types to avoid possible alignment. 1175Smax.romanov@nginx.com typedef struct { 1275Smax.romanov@nginx.com int32_t pid; 1375Smax.romanov@nginx.com uint32_t port_id; 1475Smax.romanov@nginx.com } nxt_pid_port_id_t; 1575Smax.romanov@nginx.com 1675Smax.romanov@nginx.com 1775Smax.romanov@nginx.com static nxt_int_t 1875Smax.romanov@nginx.com nxt_port_hash_test(nxt_lvlhsh_query_t *lhq, void *data) 1975Smax.romanov@nginx.com { 2075Smax.romanov@nginx.com nxt_port_t *port; 2175Smax.romanov@nginx.com nxt_pid_port_id_t *pid_port_id; 2275Smax.romanov@nginx.com 2375Smax.romanov@nginx.com port = data; 2475Smax.romanov@nginx.com pid_port_id = (nxt_pid_port_id_t *) lhq->key.start; 2575Smax.romanov@nginx.com 26277Sigor@sysoev.ru if (lhq->key.length == sizeof(nxt_pid_port_id_t) 27277Sigor@sysoev.ru && pid_port_id->pid == port->pid 28277Sigor@sysoev.ru && pid_port_id->port_id == port->id) 29277Sigor@sysoev.ru { 3075Smax.romanov@nginx.com return NXT_OK; 3175Smax.romanov@nginx.com } 3275Smax.romanov@nginx.com 3375Smax.romanov@nginx.com return NXT_DECLINED; 3475Smax.romanov@nginx.com } 3575Smax.romanov@nginx.com 3675Smax.romanov@nginx.com static const nxt_lvlhsh_proto_t lvlhsh_ports_proto nxt_aligned(64) = { 3775Smax.romanov@nginx.com NXT_LVLHSH_DEFAULT, 3875Smax.romanov@nginx.com nxt_port_hash_test, 3975Smax.romanov@nginx.com nxt_lvlhsh_alloc, 4075Smax.romanov@nginx.com nxt_lvlhsh_free, 4175Smax.romanov@nginx.com }; 4275Smax.romanov@nginx.com 4375Smax.romanov@nginx.com 4475Smax.romanov@nginx.com nxt_port_t * 45*597Sigor@sysoev.ru nxt_port_hash_retrieve(nxt_lvlhsh_t *port_hash) 4675Smax.romanov@nginx.com { 47*597Sigor@sysoev.ru return nxt_lvlhsh_retrieve(port_hash, &lvlhsh_ports_proto, NULL); 4875Smax.romanov@nginx.com } 4975Smax.romanov@nginx.com 5075Smax.romanov@nginx.com 51341Smax.romanov@nginx.com nxt_inline void 52341Smax.romanov@nginx.com nxt_port_hash_lhq(nxt_lvlhsh_query_t *lhq, nxt_pid_port_id_t *pid_port) 53341Smax.romanov@nginx.com { 54341Smax.romanov@nginx.com lhq->key_hash = nxt_murmur_hash2(pid_port, sizeof(nxt_pid_port_id_t)); 55341Smax.romanov@nginx.com lhq->key.length = sizeof(nxt_pid_port_id_t); 56341Smax.romanov@nginx.com lhq->key.start = (u_char *) pid_port; 57341Smax.romanov@nginx.com lhq->proto = &lvlhsh_ports_proto; 58341Smax.romanov@nginx.com lhq->pool = NULL; 59341Smax.romanov@nginx.com } 60341Smax.romanov@nginx.com 61341Smax.romanov@nginx.com 62348Smax.romanov@nginx.com nxt_int_t 63341Smax.romanov@nginx.com nxt_port_hash_add(nxt_lvlhsh_t *port_hash, nxt_port_t *port) 6475Smax.romanov@nginx.com { 65348Smax.romanov@nginx.com nxt_int_t res; 6675Smax.romanov@nginx.com nxt_pid_port_id_t pid_port; 6775Smax.romanov@nginx.com nxt_lvlhsh_query_t lhq; 6875Smax.romanov@nginx.com 6975Smax.romanov@nginx.com pid_port.pid = port->pid; 7075Smax.romanov@nginx.com pid_port.port_id = port->id; 7175Smax.romanov@nginx.com 72341Smax.romanov@nginx.com nxt_port_hash_lhq(&lhq, &pid_port); 7375Smax.romanov@nginx.com lhq.replace = 0; 7475Smax.romanov@nginx.com lhq.value = port; 7575Smax.romanov@nginx.com 76348Smax.romanov@nginx.com res = nxt_lvlhsh_insert(port_hash, &lhq); 77348Smax.romanov@nginx.com 78348Smax.romanov@nginx.com switch (res) { 7975Smax.romanov@nginx.com 8075Smax.romanov@nginx.com case NXT_OK: 8175Smax.romanov@nginx.com break; 8275Smax.romanov@nginx.com 8375Smax.romanov@nginx.com default: 8475Smax.romanov@nginx.com nxt_thread_log_error(NXT_LOG_WARN, "port #%d for pid %PI add failed", 8575Smax.romanov@nginx.com port->id, port->pid); 8675Smax.romanov@nginx.com break; 8775Smax.romanov@nginx.com } 88348Smax.romanov@nginx.com 89348Smax.romanov@nginx.com return res; 9075Smax.romanov@nginx.com } 9175Smax.romanov@nginx.com 9275Smax.romanov@nginx.com 93348Smax.romanov@nginx.com nxt_int_t 94341Smax.romanov@nginx.com nxt_port_hash_remove(nxt_lvlhsh_t *port_hash, nxt_port_t *port) 9575Smax.romanov@nginx.com { 96348Smax.romanov@nginx.com nxt_int_t res; 9775Smax.romanov@nginx.com nxt_pid_port_id_t pid_port; 9875Smax.romanov@nginx.com nxt_lvlhsh_query_t lhq; 9975Smax.romanov@nginx.com 10075Smax.romanov@nginx.com pid_port.pid = port->pid; 10175Smax.romanov@nginx.com pid_port.port_id = port->id; 10275Smax.romanov@nginx.com 103341Smax.romanov@nginx.com nxt_port_hash_lhq(&lhq, &pid_port); 10475Smax.romanov@nginx.com 105348Smax.romanov@nginx.com res = nxt_lvlhsh_delete(port_hash, &lhq); 106348Smax.romanov@nginx.com 107348Smax.romanov@nginx.com switch (res) { 10875Smax.romanov@nginx.com 10975Smax.romanov@nginx.com case NXT_OK: 11075Smax.romanov@nginx.com break; 11175Smax.romanov@nginx.com 11275Smax.romanov@nginx.com default: 113348Smax.romanov@nginx.com nxt_thread_log_error(NXT_LOG_WARN, "port #%d for pid %PI remove failed", 114348Smax.romanov@nginx.com port->id, port->pid); 11575Smax.romanov@nginx.com break; 11675Smax.romanov@nginx.com } 117348Smax.romanov@nginx.com 118348Smax.romanov@nginx.com return res; 11975Smax.romanov@nginx.com } 12075Smax.romanov@nginx.com 12175Smax.romanov@nginx.com 12275Smax.romanov@nginx.com nxt_port_t * 12375Smax.romanov@nginx.com nxt_port_hash_find(nxt_lvlhsh_t *port_hash, nxt_pid_t pid, 12475Smax.romanov@nginx.com nxt_port_id_t port_id) 12575Smax.romanov@nginx.com { 12675Smax.romanov@nginx.com nxt_pid_port_id_t pid_port; 12775Smax.romanov@nginx.com nxt_lvlhsh_query_t lhq; 12875Smax.romanov@nginx.com 12975Smax.romanov@nginx.com pid_port.pid = pid; 13075Smax.romanov@nginx.com pid_port.port_id = port_id; 13175Smax.romanov@nginx.com 132341Smax.romanov@nginx.com nxt_port_hash_lhq(&lhq, &pid_port); 13375Smax.romanov@nginx.com 13475Smax.romanov@nginx.com if (nxt_lvlhsh_find(port_hash, &lhq) == NXT_OK) { 13575Smax.romanov@nginx.com nxt_thread_log_debug("process port (%PI, %d) found", pid, port_id); 13675Smax.romanov@nginx.com return lhq.value; 13775Smax.romanov@nginx.com } 13875Smax.romanov@nginx.com 13975Smax.romanov@nginx.com nxt_thread_log_debug("process port (%PI, %d) not found", pid, port_id); 14075Smax.romanov@nginx.com 14175Smax.romanov@nginx.com return NULL; 14275Smax.romanov@nginx.com } 143