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
nxt_port_hash_test(nxt_lvlhsh_query_t * lhq,void * data)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 *
nxt_port_hash_retrieve(nxt_lvlhsh_t * port_hash)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
nxt_port_hash_lhq(nxt_lvlhsh_query_t * lhq,nxt_pid_port_id_t * pid_port)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
nxt_port_hash_add(nxt_lvlhsh_t * port_hash,nxt_port_t * port)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
nxt_port_hash_remove(nxt_lvlhsh_t * port_hash,nxt_port_t * port)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 *
nxt_port_hash_find(nxt_lvlhsh_t * port_hash,nxt_pid_t pid,nxt_port_id_t port_id)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