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_log(ev->task, NXT_LOG_CRIT, "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_log(task, NXT_LOG_CRIT, "fd event %d not found in hash", fd); 130 } 131