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 * 4575Smax.romanov@nginx.com nxt_port_hash_first(nxt_lvlhsh_t *port_hash, nxt_lvlhsh_each_t *lhe) 4675Smax.romanov@nginx.com { 4775Smax.romanov@nginx.com nxt_memzero(lhe, sizeof(nxt_lvlhsh_each_t)); 4875Smax.romanov@nginx.com 4975Smax.romanov@nginx.com lhe->proto = &lvlhsh_ports_proto; 5075Smax.romanov@nginx.com 5175Smax.romanov@nginx.com return nxt_port_hash_next(port_hash, lhe); 5275Smax.romanov@nginx.com } 5375Smax.romanov@nginx.com 5475Smax.romanov@nginx.com 55341Smax.romanov@nginx.com nxt_inline void 56341Smax.romanov@nginx.com nxt_port_hash_lhq(nxt_lvlhsh_query_t *lhq, nxt_pid_port_id_t *pid_port) 57341Smax.romanov@nginx.com { 58341Smax.romanov@nginx.com lhq->key_hash = nxt_murmur_hash2(pid_port, sizeof(nxt_pid_port_id_t)); 59341Smax.romanov@nginx.com lhq->key.length = sizeof(nxt_pid_port_id_t); 60341Smax.romanov@nginx.com lhq->key.start = (u_char *) pid_port; 61341Smax.romanov@nginx.com lhq->proto = &lvlhsh_ports_proto; 62341Smax.romanov@nginx.com lhq->pool = NULL; 63341Smax.romanov@nginx.com } 64341Smax.romanov@nginx.com 65341Smax.romanov@nginx.com 66*348Smax.romanov@nginx.com nxt_int_t 67341Smax.romanov@nginx.com nxt_port_hash_add(nxt_lvlhsh_t *port_hash, nxt_port_t *port) 6875Smax.romanov@nginx.com { 69*348Smax.romanov@nginx.com nxt_int_t res; 7075Smax.romanov@nginx.com nxt_pid_port_id_t pid_port; 7175Smax.romanov@nginx.com nxt_lvlhsh_query_t lhq; 7275Smax.romanov@nginx.com 7375Smax.romanov@nginx.com pid_port.pid = port->pid; 7475Smax.romanov@nginx.com pid_port.port_id = port->id; 7575Smax.romanov@nginx.com 76341Smax.romanov@nginx.com nxt_port_hash_lhq(&lhq, &pid_port); 7775Smax.romanov@nginx.com lhq.replace = 0; 7875Smax.romanov@nginx.com lhq.value = port; 7975Smax.romanov@nginx.com 80*348Smax.romanov@nginx.com res = nxt_lvlhsh_insert(port_hash, &lhq); 81*348Smax.romanov@nginx.com 82*348Smax.romanov@nginx.com switch (res) { 8375Smax.romanov@nginx.com 8475Smax.romanov@nginx.com case NXT_OK: 8575Smax.romanov@nginx.com break; 8675Smax.romanov@nginx.com 8775Smax.romanov@nginx.com default: 8875Smax.romanov@nginx.com nxt_thread_log_error(NXT_LOG_WARN, "port #%d for pid %PI add failed", 8975Smax.romanov@nginx.com port->id, port->pid); 9075Smax.romanov@nginx.com break; 9175Smax.romanov@nginx.com } 92*348Smax.romanov@nginx.com 93*348Smax.romanov@nginx.com return res; 9475Smax.romanov@nginx.com } 9575Smax.romanov@nginx.com 9675Smax.romanov@nginx.com 97*348Smax.romanov@nginx.com nxt_int_t 98341Smax.romanov@nginx.com nxt_port_hash_remove(nxt_lvlhsh_t *port_hash, nxt_port_t *port) 9975Smax.romanov@nginx.com { 100*348Smax.romanov@nginx.com nxt_int_t res; 10175Smax.romanov@nginx.com nxt_pid_port_id_t pid_port; 10275Smax.romanov@nginx.com nxt_lvlhsh_query_t lhq; 10375Smax.romanov@nginx.com 10475Smax.romanov@nginx.com pid_port.pid = port->pid; 10575Smax.romanov@nginx.com pid_port.port_id = port->id; 10675Smax.romanov@nginx.com 107341Smax.romanov@nginx.com nxt_port_hash_lhq(&lhq, &pid_port); 10875Smax.romanov@nginx.com 109*348Smax.romanov@nginx.com res = nxt_lvlhsh_delete(port_hash, &lhq); 110*348Smax.romanov@nginx.com 111*348Smax.romanov@nginx.com switch (res) { 11275Smax.romanov@nginx.com 11375Smax.romanov@nginx.com case NXT_OK: 11475Smax.romanov@nginx.com break; 11575Smax.romanov@nginx.com 11675Smax.romanov@nginx.com default: 117*348Smax.romanov@nginx.com nxt_thread_log_error(NXT_LOG_WARN, "port #%d for pid %PI remove failed", 118*348Smax.romanov@nginx.com port->id, port->pid); 11975Smax.romanov@nginx.com break; 12075Smax.romanov@nginx.com } 121*348Smax.romanov@nginx.com 122*348Smax.romanov@nginx.com return res; 12375Smax.romanov@nginx.com } 12475Smax.romanov@nginx.com 12575Smax.romanov@nginx.com 12675Smax.romanov@nginx.com nxt_port_t * 12775Smax.romanov@nginx.com nxt_port_hash_find(nxt_lvlhsh_t *port_hash, nxt_pid_t pid, 12875Smax.romanov@nginx.com nxt_port_id_t port_id) 12975Smax.romanov@nginx.com { 13075Smax.romanov@nginx.com nxt_pid_port_id_t pid_port; 13175Smax.romanov@nginx.com nxt_lvlhsh_query_t lhq; 13275Smax.romanov@nginx.com 13375Smax.romanov@nginx.com pid_port.pid = pid; 13475Smax.romanov@nginx.com pid_port.port_id = port_id; 13575Smax.romanov@nginx.com 136341Smax.romanov@nginx.com nxt_port_hash_lhq(&lhq, &pid_port); 13775Smax.romanov@nginx.com 13875Smax.romanov@nginx.com if (nxt_lvlhsh_find(port_hash, &lhq) == NXT_OK) { 13975Smax.romanov@nginx.com nxt_thread_log_debug("process port (%PI, %d) found", pid, port_id); 14075Smax.romanov@nginx.com return lhq.value; 14175Smax.romanov@nginx.com } 14275Smax.romanov@nginx.com 14375Smax.romanov@nginx.com nxt_thread_log_debug("process port (%PI, %d) not found", pid, port_id); 14475Smax.romanov@nginx.com 14575Smax.romanov@nginx.com return NULL; 14675Smax.romanov@nginx.com } 147