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