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