xref: /unit/src/nxt_port_hash.c (revision 277)
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 
26*277Sigor@sysoev.ru     if (lhq->key.length == sizeof(nxt_pid_port_id_t)
27*277Sigor@sysoev.ru         && pid_port_id->pid == port->pid
28*277Sigor@sysoev.ru         && pid_port_id->port_id == port->id)
29*277Sigor@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 
5575Smax.romanov@nginx.com void
5675Smax.romanov@nginx.com nxt_port_hash_add(nxt_lvlhsh_t *port_hash, nxt_mp_t *mem_pool,
5775Smax.romanov@nginx.com     nxt_port_t *port)
5875Smax.romanov@nginx.com {
5975Smax.romanov@nginx.com     nxt_pid_port_id_t   pid_port;
6075Smax.romanov@nginx.com     nxt_lvlhsh_query_t  lhq;
6175Smax.romanov@nginx.com 
6275Smax.romanov@nginx.com     pid_port.pid = port->pid;
6375Smax.romanov@nginx.com     pid_port.port_id = port->id;
6475Smax.romanov@nginx.com 
6575Smax.romanov@nginx.com     lhq.key_hash = nxt_murmur_hash2(&pid_port, sizeof(pid_port));
6675Smax.romanov@nginx.com     lhq.key.length = sizeof(pid_port);
6775Smax.romanov@nginx.com     lhq.key.start = (u_char *) &pid_port;
6875Smax.romanov@nginx.com     lhq.proto = &lvlhsh_ports_proto;
6975Smax.romanov@nginx.com     lhq.replace = 0;
7075Smax.romanov@nginx.com     lhq.value = port;
7175Smax.romanov@nginx.com     lhq.pool = mem_pool;
7275Smax.romanov@nginx.com 
7375Smax.romanov@nginx.com     switch (nxt_lvlhsh_insert(port_hash, &lhq)) {
7475Smax.romanov@nginx.com 
7575Smax.romanov@nginx.com     case NXT_OK:
7675Smax.romanov@nginx.com         break;
7775Smax.romanov@nginx.com 
7875Smax.romanov@nginx.com     default:
7975Smax.romanov@nginx.com         nxt_thread_log_error(NXT_LOG_WARN, "port #%d for pid %PI add failed",
8075Smax.romanov@nginx.com                              port->id, port->pid);
8175Smax.romanov@nginx.com         break;
8275Smax.romanov@nginx.com     }
8375Smax.romanov@nginx.com }
8475Smax.romanov@nginx.com 
8575Smax.romanov@nginx.com 
8675Smax.romanov@nginx.com void
8775Smax.romanov@nginx.com nxt_port_hash_remove(nxt_lvlhsh_t *port_hash, nxt_mp_t *mem_pool,
8875Smax.romanov@nginx.com     nxt_port_t *port)
8975Smax.romanov@nginx.com {
9075Smax.romanov@nginx.com     nxt_pid_port_id_t   pid_port;
9175Smax.romanov@nginx.com     nxt_lvlhsh_query_t  lhq;
9275Smax.romanov@nginx.com 
9375Smax.romanov@nginx.com     pid_port.pid = port->pid;
9475Smax.romanov@nginx.com     pid_port.port_id = port->id;
9575Smax.romanov@nginx.com 
9675Smax.romanov@nginx.com     lhq.key_hash = nxt_murmur_hash2(&pid_port, sizeof(pid_port));
9775Smax.romanov@nginx.com     lhq.key.length = sizeof(pid_port);
9875Smax.romanov@nginx.com     lhq.key.start = (u_char *) &pid_port;
9975Smax.romanov@nginx.com     lhq.proto = &lvlhsh_ports_proto;
10075Smax.romanov@nginx.com     lhq.replace = 0;
10175Smax.romanov@nginx.com     lhq.value = port;
10275Smax.romanov@nginx.com     lhq.pool = mem_pool;
10375Smax.romanov@nginx.com 
10475Smax.romanov@nginx.com     switch (nxt_lvlhsh_delete(port_hash, &lhq)) {
10575Smax.romanov@nginx.com 
10675Smax.romanov@nginx.com     case NXT_OK:
10775Smax.romanov@nginx.com         break;
10875Smax.romanov@nginx.com 
10975Smax.romanov@nginx.com     default:
11075Smax.romanov@nginx.com         break;
11175Smax.romanov@nginx.com     }
11275Smax.romanov@nginx.com }
11375Smax.romanov@nginx.com 
11475Smax.romanov@nginx.com 
11575Smax.romanov@nginx.com nxt_port_t *
11675Smax.romanov@nginx.com nxt_port_hash_find(nxt_lvlhsh_t *port_hash, nxt_pid_t pid,
11775Smax.romanov@nginx.com     nxt_port_id_t port_id)
11875Smax.romanov@nginx.com {
11975Smax.romanov@nginx.com     nxt_pid_port_id_t   pid_port;
12075Smax.romanov@nginx.com     nxt_lvlhsh_query_t  lhq;
12175Smax.romanov@nginx.com 
12275Smax.romanov@nginx.com     pid_port.pid = pid;
12375Smax.romanov@nginx.com     pid_port.port_id = port_id;
12475Smax.romanov@nginx.com 
12575Smax.romanov@nginx.com     lhq.key_hash = nxt_murmur_hash2(&pid_port, sizeof(pid_port));
12675Smax.romanov@nginx.com     lhq.key.length = sizeof(pid_port);
12775Smax.romanov@nginx.com     lhq.key.start = (u_char *) &pid_port;
12875Smax.romanov@nginx.com     lhq.proto = &lvlhsh_ports_proto;
12975Smax.romanov@nginx.com 
13075Smax.romanov@nginx.com     /* TODO lock ports */
13175Smax.romanov@nginx.com 
13275Smax.romanov@nginx.com     if (nxt_lvlhsh_find(port_hash, &lhq) == NXT_OK) {
13375Smax.romanov@nginx.com         nxt_thread_log_debug("process port (%PI, %d) found", pid, port_id);
13475Smax.romanov@nginx.com         return lhq.value;
13575Smax.romanov@nginx.com     }
13675Smax.romanov@nginx.com 
13775Smax.romanov@nginx.com     nxt_thread_log_debug("process port (%PI, %d) not found", pid, port_id);
13875Smax.romanov@nginx.com 
13975Smax.romanov@nginx.com     return NULL;
14075Smax.romanov@nginx.com }
141