Changes in uspace/srv/ns/service.c [4e00f87:b72efe8] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/ns/service.c
r4e00f87 rb72efe8 40 40 #include "ns.h" 41 41 42 #define SERVICE_HASH_TABLE_CHAINS 20 42 43 43 44 /** Service hash table item. */ 44 45 typedef struct { 45 ht_link_t link;46 link_t link; 46 47 sysarg_t service; /**< Service ID. */ 47 48 sysarg_t phone; /**< Phone registered with the service. */ … … 49 50 } hashed_service_t; 50 51 51 52 static size_t service_key_hash(void *key) 53 { 54 return *(sysarg_t*)key; 55 } 56 57 static size_t service_hash(const ht_link_t *item) 58 { 59 hashed_service_t *hs = hash_table_get_inst(item, hashed_service_t, link); 60 return hs->service; 61 } 62 63 static bool service_key_equal(void *key, const ht_link_t *item) 64 { 65 hashed_service_t *hs = hash_table_get_inst(item, hashed_service_t, link); 66 return hs->service == *(sysarg_t*)key; 52 /** Compute hash index into service hash table. 53 * 54 * @param key Pointer keys. However, only the first key (i.e. service number) 55 * is used to compute the hash index. 56 * 57 * @return Hash index corresponding to key[0]. 58 * 59 */ 60 static hash_index_t service_hash(unsigned long key[]) 61 { 62 assert(key); 63 return (key[0] % SERVICE_HASH_TABLE_CHAINS); 64 } 65 66 /** Compare a key with hashed item. 67 * 68 * This compare function always ignores the third key. 69 * It exists only to make it possible to remove records 70 * originating from connection with key[1] in_phone_hash 71 * value. Note that this is close to being classified 72 * as a nasty hack. 73 * 74 * @param key Array of keys. 75 * @param keys Must be lesser or equal to 3. 76 * @param item Pointer to a hash table item. 77 * 78 * @return Non-zero if the key matches the item, zero otherwise. 79 * 80 */ 81 static int service_compare(unsigned long key[], hash_count_t keys, link_t *item) 82 { 83 assert(key); 84 assert(keys <= 3); 85 assert(item); 86 87 hashed_service_t *hs = hash_table_get_instance(item, hashed_service_t, link); 88 89 if (keys == 2) 90 return ((key[0] == hs->service) && (key[1] == hs->in_phone_hash)); 91 else 92 return (key[0] == hs->service); 93 } 94 95 /** Perform actions after removal of item from the hash table. 96 * 97 * @param item Item that was removed from the hash table. 98 * 99 */ 100 static void service_remove(link_t *item) 101 { 102 assert(item); 103 free(hash_table_get_instance(item, hashed_service_t, link)); 67 104 } 68 105 69 106 /** Operations for service hash table. */ 70 static hash_table_op s_t service_hash_table_ops = {107 static hash_table_operations_t service_hash_table_ops = { 71 108 .hash = service_hash, 72 .key_hash = service_key_hash, 73 .key_equal = service_key_equal, 74 .equal = NULL, 75 .remove_callback = NULL 109 .compare = service_compare, 110 .remove_callback = service_remove 76 111 }; 77 112 … … 92 127 int service_init(void) 93 128 { 94 if (!hash_table_create(&service_hash_table, 0, 0, &service_hash_table_ops)) { 129 if (!hash_table_create(&service_hash_table, SERVICE_HASH_TABLE_CHAINS, 130 3, &service_hash_table_ops)) { 95 131 printf(NAME ": No memory available for services\n"); 96 132 return ENOMEM; … … 109 145 pending_conn_t *pr = list_get_instance(cur, pending_conn_t, link); 110 146 111 ht_link_t *link = hash_table_find(&service_hash_table, &pr->service); 147 unsigned long keys[3] = { 148 pr->service, 149 0, 150 0 151 }; 152 153 link_t *link = hash_table_find(&service_hash_table, keys); 112 154 if (!link) 113 155 continue; 114 156 115 hashed_service_t *hs = hash_table_get_inst (link, hashed_service_t, link);157 hashed_service_t *hs = hash_table_get_instance(link, hashed_service_t, link); 116 158 (void) ipc_forward_fast(pr->callid, hs->phone, pr->arg2, 117 159 pr->arg3, 0, IPC_FF_NONE); … … 134 176 int register_service(sysarg_t service, sysarg_t phone, ipc_call_t *call) 135 177 { 136 if (hash_table_find(&service_hash_table, &service)) 178 unsigned long keys[3] = { 179 service, 180 call->in_phone_hash, 181 0 182 }; 183 184 if (hash_table_find(&service_hash_table, keys)) 137 185 return EEXISTS; 138 186 … … 141 189 return ENOMEM; 142 190 191 link_initialize(&hs->link); 143 192 hs->service = service; 144 193 hs->phone = phone; 145 194 hs->in_phone_hash = call->in_phone_hash; 146 hash_table_insert(&service_hash_table, &hs->link);195 hash_table_insert(&service_hash_table, keys, &hs->link); 147 196 148 197 return EOK; … … 161 210 { 162 211 sysarg_t retval; 163 164 ht_link_t *link = hash_table_find(&service_hash_table, &service); 212 unsigned long keys[3] = { 213 service, 214 0, 215 0 216 }; 217 218 link_t *link = hash_table_find(&service_hash_table, keys); 165 219 if (!link) { 166 220 if (IPC_GET_ARG4(*call) & IPC_FLAG_BLOCKING) { … … 185 239 } 186 240 187 hashed_service_t *hs = hash_table_get_inst (link, hashed_service_t, link);241 hashed_service_t *hs = hash_table_get_instance(link, hashed_service_t, link); 188 242 (void) ipc_forward_fast(callid, hs->phone, IPC_GET_ARG2(*call), 189 243 IPC_GET_ARG3(*call), 0, IPC_FF_NONE);
Note:
See TracChangeset
for help on using the changeset viewer.