Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/ns/service.c

    r4e00f87 rb72efe8  
    4040#include "ns.h"
    4141
     42#define SERVICE_HASH_TABLE_CHAINS  20
    4243
    4344/** Service hash table item. */
    4445typedef struct {
    45         ht_link_t link;
     46        link_t link;
    4647        sysarg_t service;        /**< Service ID. */
    4748        sysarg_t phone;          /**< Phone registered with the service. */
     
    4950} hashed_service_t;
    5051
    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 */
     60static 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 */
     81static 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 */
     100static void service_remove(link_t *item)
     101{
     102        assert(item);
     103        free(hash_table_get_instance(item, hashed_service_t, link));
    67104}
    68105
    69106/** Operations for service hash table. */
    70 static hash_table_ops_t service_hash_table_ops = {
     107static hash_table_operations_t service_hash_table_ops = {
    71108        .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
    76111};
    77112
     
    92127int service_init(void)
    93128{
    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)) {
    95131                printf(NAME ": No memory available for services\n");
    96132                return ENOMEM;
     
    109145                pending_conn_t *pr = list_get_instance(cur, pending_conn_t, link);
    110146               
    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);
    112154                if (!link)
    113155                        continue;
    114156               
    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);
    116158                (void) ipc_forward_fast(pr->callid, hs->phone, pr->arg2,
    117159                    pr->arg3, 0, IPC_FF_NONE);
     
    134176int register_service(sysarg_t service, sysarg_t phone, ipc_call_t *call)
    135177{
    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))
    137185                return EEXISTS;
    138186       
     
    141189                return ENOMEM;
    142190       
     191        link_initialize(&hs->link);
    143192        hs->service = service;
    144193        hs->phone = phone;
    145194        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);
    147196       
    148197        return EOK;
     
    161210{
    162211        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);
    165219        if (!link) {
    166220                if (IPC_GET_ARG4(*call) & IPC_FLAG_BLOCKING) {
     
    185239        }
    186240       
    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);
    188242        (void) ipc_forward_fast(callid, hs->phone, IPC_GET_ARG2(*call),
    189243            IPC_GET_ARG3(*call), 0, IPC_FF_NONE);
Note: See TracChangeset for help on using the changeset viewer.