xref: /unit/src/nxt_port_hash.c (revision 75)
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