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
nxt_fd_event_hash_test(nxt_lvlhsh_query_t * lhq,void * data)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
nxt_fd_event_hash_add(nxt_lvlhsh_t * lvlhsh,nxt_fd_t fd,nxt_fd_event_t * ev)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 *
nxt_fd_event_hash_get(nxt_task_t * task,nxt_lvlhsh_t * lvlhsh,nxt_fd_t fd)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
nxt_fd_event_hash_delete(nxt_task_t * task,nxt_lvlhsh_t * lvlhsh,nxt_fd_t fd,nxt_bool_t ignore)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
nxt_fd_event_hash_destroy(nxt_lvlhsh_t * lvlhsh)97 nxt_fd_event_hash_destroy(nxt_lvlhsh_t *lvlhsh)
98 {
99 nxt_fd_event_t *ev;
100
101 do {
102 ev = nxt_lvlhsh_retrieve(lvlhsh, &nxt_event_set_fd_hash_proto, NULL);
103
104 } while (ev != NULL);
105 }
106
107
108 static void
nxt_fd_event_hash_error(nxt_task_t * task,nxt_fd_t fd)109 nxt_fd_event_hash_error(nxt_task_t *task, nxt_fd_t fd)
110 {
111 nxt_alert(task, "fd event %d not found in hash", fd);
112 }
113