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