xref: /unit/src/nxt_fd_event.c (revision 12:477899a6661b)
1 
2 /*
3  * Copyright (C) Igor Sysoev
4  * Copyright (C) NGINX, Inc.
5  */
6 
7 #include <nxt_main.h>
8 
9 
10 static nxt_int_t nxt_fd_event_hash_test(nxt_lvlhsh_query_t *lhq, void *data);
11 static void nxt_fd_event_hash_error(nxt_task_t *task, nxt_fd_t fd);
12 
13 
14 static const nxt_lvlhsh_proto_t  nxt_event_set_fd_hash_proto  nxt_aligned(64) =
15 {
16     NXT_LVLHSH_LARGE_MEMALIGN,
17     0,
18     nxt_fd_event_hash_test,
19     nxt_lvlhsh_alloc,
20     nxt_lvlhsh_free,
21 };
22 
23 
24 /* nxt_murmur_hash2() is unique for 4 bytes. */
25 
26 static nxt_int_t
27 nxt_fd_event_hash_test(nxt_lvlhsh_query_t *lhq, void *data)
28 {
29     return NXT_OK;
30 }
31 
32 
33 nxt_int_t
34 nxt_fd_event_hash_add(nxt_lvlhsh_t *lvlhsh, nxt_fd_t fd, nxt_fd_event_t *ev)
35 {
36     nxt_int_t           ret;
37     nxt_lvlhsh_query_t  lhq;
38 
39     lhq.key_hash = nxt_murmur_hash2(&fd, sizeof(nxt_fd_t));
40     lhq.replace = 0;
41     lhq.value = ev;
42     lhq.proto = &nxt_event_set_fd_hash_proto;
43 
44     ret = nxt_lvlhsh_insert(lvlhsh, &lhq);
45 
46     if (nxt_fast_path(ret == NXT_OK)) {
47         return NXT_OK;
48     }
49 
50     nxt_log(ev->task, NXT_LOG_CRIT, "fd event %d is already in hash", ev->fd);
51 
52     return NXT_ERROR;
53 }
54 
55 
56 void *
57 nxt_fd_event_hash_get(nxt_task_t *task, nxt_lvlhsh_t *lvlhsh, nxt_fd_t fd)
58 {
59     nxt_int_t           ret;
60     nxt_lvlhsh_query_t  lhq;
61 
62     lhq.key_hash = nxt_murmur_hash2(&fd, sizeof(nxt_fd_t));
63     lhq.proto = &nxt_event_set_fd_hash_proto;
64 
65     ret = nxt_lvlhsh_find(lvlhsh, &lhq);
66 
67     if (nxt_fast_path(ret == NXT_OK)) {
68         return lhq.value;
69     }
70 
71     nxt_fd_event_hash_error(task, fd);
72 
73     return NULL;
74 }
75 
76 
77 void
78 nxt_fd_event_hash_delete(nxt_task_t *task, nxt_lvlhsh_t *lvlhsh, nxt_fd_t fd,
79     nxt_bool_t ignore)
80 {
81     nxt_int_t           ret;
82     nxt_lvlhsh_query_t  lhq;
83 
84     lhq.key_hash = nxt_murmur_hash2(&fd, sizeof(nxt_fd_t));
85     lhq.proto = &nxt_event_set_fd_hash_proto;
86 
87     ret = nxt_lvlhsh_delete(lvlhsh, &lhq);
88 
89     if (nxt_slow_path(ret != NXT_OK)) {
90         if (!ignore) {
91             nxt_fd_event_hash_error(task, fd);
92         }
93     }
94 }
95 
96 
97 void
98 nxt_fd_event_hash_destroy(nxt_lvlhsh_t *lvlhsh)
99 {
100     nxt_int_t           ret;
101     nxt_fd_event_t      *ev;
102     nxt_lvlhsh_each_t   lhe;
103     nxt_lvlhsh_query_t  lhq;
104 
105     nxt_memzero(&lhe, sizeof(nxt_lvlhsh_each_t));
106     lhe.proto = &nxt_event_set_fd_hash_proto;
107     lhq.proto = &nxt_event_set_fd_hash_proto;
108 
109     for ( ;; ) {
110         ev = nxt_lvlhsh_each(lvlhsh, &lhe);
111 
112         if (ev == NULL) {
113             return;
114         }
115 
116         lhq.key_hash = nxt_murmur_hash2(&ev->fd, sizeof(nxt_fd_t));
117 
118         ret = nxt_lvlhsh_delete(lvlhsh, &lhq);
119 
120         if (nxt_slow_path(ret != NXT_OK)) {
121             nxt_fd_event_hash_error(ev->task, ev->fd);
122         }
123     }
124 }
125 
126 
127 static void
128 nxt_fd_event_hash_error(nxt_task_t *task, nxt_fd_t fd)
129 {
130     nxt_log(task, NXT_LOG_CRIT, "fd event %d not found in hash", fd);
131 }
132