1*75Smax.romanov@nginx.com 2*75Smax.romanov@nginx.com /* 3*75Smax.romanov@nginx.com * Copyright (C) Max Romanov 4*75Smax.romanov@nginx.com * Copyright (C) NGINX, Inc. 5*75Smax.romanov@nginx.com */ 6*75Smax.romanov@nginx.com 7*75Smax.romanov@nginx.com #include <nxt_port_hash.h> 8*75Smax.romanov@nginx.com 9*75Smax.romanov@nginx.com 10*75Smax.romanov@nginx.com // Explicitly using 32 bit types to avoid possible alignment. 11*75Smax.romanov@nginx.com typedef struct { 12*75Smax.romanov@nginx.com int32_t pid; 13*75Smax.romanov@nginx.com uint32_t port_id; 14*75Smax.romanov@nginx.com } nxt_pid_port_id_t; 15*75Smax.romanov@nginx.com 16*75Smax.romanov@nginx.com 17*75Smax.romanov@nginx.com static nxt_int_t 18*75Smax.romanov@nginx.com nxt_port_hash_test(nxt_lvlhsh_query_t *lhq, void *data) 19*75Smax.romanov@nginx.com { 20*75Smax.romanov@nginx.com nxt_port_t *port; 21*75Smax.romanov@nginx.com nxt_pid_port_id_t *pid_port_id; 22*75Smax.romanov@nginx.com 23*75Smax.romanov@nginx.com port = data; 24*75Smax.romanov@nginx.com pid_port_id = (nxt_pid_port_id_t *) lhq->key.start; 25*75Smax.romanov@nginx.com 26*75Smax.romanov@nginx.com if (lhq->key.length == sizeof(nxt_pid_port_id_t) && 27*75Smax.romanov@nginx.com pid_port_id->pid == port->pid && 28*75Smax.romanov@nginx.com pid_port_id->port_id == port->id) { 29*75Smax.romanov@nginx.com return NXT_OK; 30*75Smax.romanov@nginx.com } 31*75Smax.romanov@nginx.com 32*75Smax.romanov@nginx.com return NXT_DECLINED; 33*75Smax.romanov@nginx.com } 34*75Smax.romanov@nginx.com 35*75Smax.romanov@nginx.com static const nxt_lvlhsh_proto_t lvlhsh_ports_proto nxt_aligned(64) = { 36*75Smax.romanov@nginx.com NXT_LVLHSH_DEFAULT, 37*75Smax.romanov@nginx.com nxt_port_hash_test, 38*75Smax.romanov@nginx.com nxt_lvlhsh_alloc, 39*75Smax.romanov@nginx.com nxt_lvlhsh_free, 40*75Smax.romanov@nginx.com }; 41*75Smax.romanov@nginx.com 42*75Smax.romanov@nginx.com 43*75Smax.romanov@nginx.com nxt_port_t * 44*75Smax.romanov@nginx.com nxt_port_hash_first(nxt_lvlhsh_t *port_hash, nxt_lvlhsh_each_t *lhe) 45*75Smax.romanov@nginx.com { 46*75Smax.romanov@nginx.com nxt_memzero(lhe, sizeof(nxt_lvlhsh_each_t)); 47*75Smax.romanov@nginx.com 48*75Smax.romanov@nginx.com lhe->proto = &lvlhsh_ports_proto; 49*75Smax.romanov@nginx.com 50*75Smax.romanov@nginx.com return nxt_port_hash_next(port_hash, lhe); 51*75Smax.romanov@nginx.com } 52*75Smax.romanov@nginx.com 53*75Smax.romanov@nginx.com 54*75Smax.romanov@nginx.com void 55*75Smax.romanov@nginx.com nxt_port_hash_add(nxt_lvlhsh_t *port_hash, nxt_mp_t *mem_pool, 56*75Smax.romanov@nginx.com nxt_port_t *port) 57*75Smax.romanov@nginx.com { 58*75Smax.romanov@nginx.com nxt_pid_port_id_t pid_port; 59*75Smax.romanov@nginx.com nxt_lvlhsh_query_t lhq; 60*75Smax.romanov@nginx.com 61*75Smax.romanov@nginx.com pid_port.pid = port->pid; 62*75Smax.romanov@nginx.com pid_port.port_id = port->id; 63*75Smax.romanov@nginx.com 64*75Smax.romanov@nginx.com lhq.key_hash = nxt_murmur_hash2(&pid_port, sizeof(pid_port)); 65*75Smax.romanov@nginx.com lhq.key.length = sizeof(pid_port); 66*75Smax.romanov@nginx.com lhq.key.start = (u_char *) &pid_port; 67*75Smax.romanov@nginx.com lhq.proto = &lvlhsh_ports_proto; 68*75Smax.romanov@nginx.com lhq.replace = 0; 69*75Smax.romanov@nginx.com lhq.value = port; 70*75Smax.romanov@nginx.com lhq.pool = mem_pool; 71*75Smax.romanov@nginx.com 72*75Smax.romanov@nginx.com switch (nxt_lvlhsh_insert(port_hash, &lhq)) { 73*75Smax.romanov@nginx.com 74*75Smax.romanov@nginx.com case NXT_OK: 75*75Smax.romanov@nginx.com break; 76*75Smax.romanov@nginx.com 77*75Smax.romanov@nginx.com default: 78*75Smax.romanov@nginx.com nxt_thread_log_error(NXT_LOG_WARN, "port #%d for pid %PI add failed", 79*75Smax.romanov@nginx.com port->id, port->pid); 80*75Smax.romanov@nginx.com break; 81*75Smax.romanov@nginx.com } 82*75Smax.romanov@nginx.com } 83*75Smax.romanov@nginx.com 84*75Smax.romanov@nginx.com 85*75Smax.romanov@nginx.com void 86*75Smax.romanov@nginx.com nxt_port_hash_remove(nxt_lvlhsh_t *port_hash, nxt_mp_t *mem_pool, 87*75Smax.romanov@nginx.com nxt_port_t *port) 88*75Smax.romanov@nginx.com { 89*75Smax.romanov@nginx.com nxt_pid_port_id_t pid_port; 90*75Smax.romanov@nginx.com nxt_lvlhsh_query_t lhq; 91*75Smax.romanov@nginx.com 92*75Smax.romanov@nginx.com pid_port.pid = port->pid; 93*75Smax.romanov@nginx.com pid_port.port_id = port->id; 94*75Smax.romanov@nginx.com 95*75Smax.romanov@nginx.com lhq.key_hash = nxt_murmur_hash2(&pid_port, sizeof(pid_port)); 96*75Smax.romanov@nginx.com lhq.key.length = sizeof(pid_port); 97*75Smax.romanov@nginx.com lhq.key.start = (u_char *) &pid_port; 98*75Smax.romanov@nginx.com lhq.proto = &lvlhsh_ports_proto; 99*75Smax.romanov@nginx.com lhq.replace = 0; 100*75Smax.romanov@nginx.com lhq.value = port; 101*75Smax.romanov@nginx.com lhq.pool = mem_pool; 102*75Smax.romanov@nginx.com 103*75Smax.romanov@nginx.com switch (nxt_lvlhsh_delete(port_hash, &lhq)) { 104*75Smax.romanov@nginx.com 105*75Smax.romanov@nginx.com case NXT_OK: 106*75Smax.romanov@nginx.com break; 107*75Smax.romanov@nginx.com 108*75Smax.romanov@nginx.com default: 109*75Smax.romanov@nginx.com break; 110*75Smax.romanov@nginx.com } 111*75Smax.romanov@nginx.com } 112*75Smax.romanov@nginx.com 113*75Smax.romanov@nginx.com 114*75Smax.romanov@nginx.com nxt_port_t * 115*75Smax.romanov@nginx.com nxt_port_hash_find(nxt_lvlhsh_t *port_hash, nxt_pid_t pid, 116*75Smax.romanov@nginx.com nxt_port_id_t port_id) 117*75Smax.romanov@nginx.com { 118*75Smax.romanov@nginx.com nxt_pid_port_id_t pid_port; 119*75Smax.romanov@nginx.com nxt_lvlhsh_query_t lhq; 120*75Smax.romanov@nginx.com 121*75Smax.romanov@nginx.com pid_port.pid = pid; 122*75Smax.romanov@nginx.com pid_port.port_id = port_id; 123*75Smax.romanov@nginx.com 124*75Smax.romanov@nginx.com lhq.key_hash = nxt_murmur_hash2(&pid_port, sizeof(pid_port)); 125*75Smax.romanov@nginx.com lhq.key.length = sizeof(pid_port); 126*75Smax.romanov@nginx.com lhq.key.start = (u_char *) &pid_port; 127*75Smax.romanov@nginx.com lhq.proto = &lvlhsh_ports_proto; 128*75Smax.romanov@nginx.com 129*75Smax.romanov@nginx.com /* TODO lock ports */ 130*75Smax.romanov@nginx.com 131*75Smax.romanov@nginx.com if (nxt_lvlhsh_find(port_hash, &lhq) == NXT_OK) { 132*75Smax.romanov@nginx.com nxt_thread_log_debug("process port (%PI, %d) found", pid, port_id); 133*75Smax.romanov@nginx.com return lhq.value; 134*75Smax.romanov@nginx.com } 135*75Smax.romanov@nginx.com 136*75Smax.romanov@nginx.com nxt_thread_log_debug("process port (%PI, %d) not found", pid, port_id); 137*75Smax.romanov@nginx.com 138*75Smax.romanov@nginx.com return NULL; 139*75Smax.romanov@nginx.com } 140