static int test_hash(void) { Hashtab *h; starttesting("hashtab"); h = hashtabnew(100, hash_cmp, hash_hash); if (!h) return endtesting(1); if (!hashtabadd(h, "one")|| !hashtabadd(h, "two")|| !hashtabadd(h, "three")|| !hashtabadd(h, "four")) return endtesting(1); printf("foreach ----\n"); hashtabforeach(h, hash_print, NULL); printf("search ----\none == %s\ntwo == %s\nthree == %s\nfour == %s\n", (char *)hashtabsearch(h, "one"), (char *)hashtabsearch(h, "two"), (char *)hashtabsearch(h, "three"), (char *)hashtabsearch(h, "four")); hashtabrelease(h); return endtesting(0); }
static ConnCacheEntry * internal_get (int32_t cell, uint32_t host, uint16_t port, uint16_t service, int (*probe)(struct rx_connection *), CredCacheEntry *ce) { ConnCacheEntry *e; ConnCacheEntry key; #if 0 if (connected_mode == DISCONNECTED) return NULL; #endif key.host = host; key.port = port; key.service = service; key.cred = ce->cred; key.securityindex = ce->securityindex; e = (ConnCacheEntry *)hashtabsearch (connhtab, (void *)&key); if (e == NULL) { ConnCacheEntry *parent = NULL; if (ce->securityindex || ce->cred) { key.cred = 0; key.securityindex = 0; parent = (ConnCacheEntry *)hashtabsearch (connhtab, (void *)&key); if (parent == NULL) { parent = add_connection (cell, host, port, service, probe, NULL); } ++parent->refcount; } e = add_connection (cell, host, port, service, probe, ce); if (parent != NULL) e->parent = parent; } /* * Since we only probe the parent entry (ie noauth), we make sure * the status from the parent entry is pushed down to the * children. */ if(e->parent != NULL) { e->flags.alivep = e->parent->flags.alivep; } return e; }
static struct ropa_client * uuid_query_simple (uint32_t host) { struct ropa_client ckey; uuid_init_simple (&ckey.uuid, host); return hashtabsearch (ht_clients_uuid, &ckey); }
int ropa_drop_callbacks (uint32_t addr, uint16_t port, const AFSCBFids *a_cbfids_p, const AFSCBs *a_cbs_p) { struct ropa_client *c; struct ropa_cb cbkey, *cb; struct ropa_ccpair cckey, *cc; int i; debug_print_callbacks(); if (a_cbfids_p->len > AFSCBMAX) return EINVAL; c = client_query (addr, port); if (c == NULL) { mlog_log (MDEBROPA, "ropa_drop_callbacks: didn't find client %x/%d", addr, port); return 0; } for (i = 0; i < a_cbfids_p->len; i++) { cbkey.fid = a_cbfids_p->val[i]; cb = hashtabsearch (ht_callbacks, &cbkey); if (cb != NULL) { cckey.client = c; cckey.cb = cb; cc = hashtabsearch (ht_ccpairs, &cckey); if (cc != NULL) { mlog_log (MDEBROPA, "ropa_drop: dropping %x.%x.%x:%x/%d", cb->fid.Volume, cb->fid.Vnode, cb->fid.Unique, addr, port); break_ccpair (cc, FALSE); } } } debug_print_callbacks(); return 0; }
int mnode_find (const AFSFid *fid, struct mnode **node) { struct mnode ptr, *res = NULL; ptr.fid = *fid; while (res == NULL) { res = hashtabsearch (mnode_htab, &ptr); if (res) { if (res->flags.removedp == TRUE) return ENOENT; if (res->li) listdel (mnode_lru, res->li); if (res->ref == 0) mnode_numfree--; res->ref++; } else if (mnode_numfree != 0) { res = listdeltail (mnode_lru); assert (res); assert (res->ref == 0); hashtabdel (mnode_htab, res); reset_node (res, fid); hashtabadd (mnode_htab, res); res->ref++; } else { /* XXX */ mlog_log (MDEBWARN, "mnode_find: no free nodes, had to malloc()"); res = malloc(sizeof(struct mnode)); if (res == NULL) { mlog_log (MDEBWARN, "mnode_find: malloc() failed"); LWP_DispatchProcess(); /* Yield */ continue; } reset_node (res, fid); hashtabadd (mnode_htab, res); res->ref++; } } assert(res->flags.removedp == FALSE); *node = res; res->li = listaddhead (mnode_lru, *node); return 0; }
static struct ropa_ccpair * add_client (struct ropa_cb *cb, struct ropa_client *c) { struct timeval tv; struct ropa_ccpair cckey, *cc; assert (cb && c); cckey.client = c; cckey.cb = cb; cc = hashtabsearch (ht_ccpairs, &cckey); if (cc) { listdel (lru_ccpair, cc->li); cc->li = listaddhead (lru_ccpair, cc); return cc; } /* The reverse of these are in break_ccpair */ callback_ref (cb); client_ref (c); cc = listdeltail (lru_ccpair); DIAGNOSTIC_CHECK_CCPAIR(cc); cc->li = NULL; if (ccpairs_inuse_p (cc)) break_ccpair (cc, TRUE); /* XXX do it for real */ gettimeofday(&tv, NULL); cc->expire = tv.tv_sec + 3600; heap_insert (heap_ccpairs, cc, &cc->heap); LWP_NoYieldSignal (heap_ccpairs); cc->cb_li = listaddtail (cb->ccpairs, cc); cc->client = c; cc->cb = cb; cc->li = listaddhead (lru_ccpair, cc); hashtabadd (ht_ccpairs, cc); mlog_log (MDEBROPA, "add_client: added %x to callback %x.%x.%x", c->addr[0].addr_in, cb->fid.Volume, cb->fid.Vnode, cb->fid.Unique); return cc; }
static struct ropa_client * client_query_notalkback (uint32_t host, uint16_t port) { struct ropa_client ckey; struct ropa_addr *addr; ckey.numberOfInterfaces = 1; ckey.addr[0].c= &ckey; ckey.addr[0].addr_in = host; ckey.port = port; addr = hashtabsearch (ht_clients_ip, &ckey.addr[0]); if (addr) { assert (addr->c->numberOfInterfaces); return addr->c; } return NULL; }
static int break_fid (const struct AFSFid *fid, struct ropa_client *c, Bool break_own) { struct ropa_cb cbkey, *cb; cbkey.fid = *fid; cb = hashtabsearch (ht_callbacks, &cbkey); if (cb == NULL) { return -1; } break_callback (cb, c, break_own); return 0; }
Symbol * addsym(char *name) { Symbol key, *s; key.name = name; s = (Symbol *) hashtabsearch(htab, (void *) &key); if (s == NULL) { s = (Symbol *) emalloc(sizeof(*s)); s->name = name; s->gen_name = estrdup(name); output_name(s->gen_name); s->stype = SUndefined; hashtabadd(htab, s); } return s; }
Bool conn_serverupp (uint32_t host, uint16_t port, uint16_t service) { ConnCacheEntry *e; ConnCacheEntry key; key.host = host; key.port = port; key.service = service; key.cred = 0; key.securityindex = 0; e = (ConnCacheEntry *)hashtabsearch (connhtab, (void *)&key); if (e != NULL) return e->flags.alivep; else return TRUE; }
int32_t conn_host2cell (uint32_t host, uint16_t port, uint16_t service) { ConnCacheEntry *e; ConnCacheEntry key; key.host = host; key.port = port; key.service = service; key.cred = 0; key.securityindex = 0; e = (ConnCacheEntry *)hashtabsearch(connhtab, (void *)&key); if (e == NULL) return -1; else return e->cell; }
void mnode_remove (const AFSFid *fid) { struct mnode ptr, *res; ptr.fid = *fid; res = hashtabsearch (mnode_htab, &ptr); if (res) { if (res->ref == 0 && res->flags.fdp) { close (res->fd); res->flags.fdp = FALSE; } if (res->li) listdel (mnode_lru, res->li); res->li = listaddhead (mnode_lru, res); res->flags.removedp = TRUE; } }
int ropa_getcallback (uint32_t host, uint16_t port, const struct AFSFid *fid, AFSCallBack *callback, int32_t voltype) { struct ropa_client *c; struct ropa_cb cbkey, *cb; struct ropa_ccpair *cc ; struct AFSFid callback_fid; debug_print_callbacks(); c = client_query (host, port); if (c == NULL) { mlog_log (MDEBROPA, "ropa_getcallback: didn't find client %x/%d", host, port); update_callback_time (DEFAULT_TIMEOUT, callback, CBSHARED); return 0; } /* * At this point the client should be firmly set * in the ropa client database. */ #if 0 if (c->have_outstanding_callbacks) break_outstanding_callbacks (c); #endif if (voltype == RWVOL) { callback_fid = *fid; } else { callback_fid.Volume = fid->Volume; callback_fid.Vnode = 0; callback_fid.Unique = 0; } cbkey.fid = callback_fid; cb = hashtabsearch (ht_callbacks, &cbkey); if (cb == NULL) { cb = listdeltail (lru_callback); DIAGNOSTIC_CHECK_CALLBACK(cb); cb->li = NULL; if (callback_inuse_p (cb)) { break_callback (cb, NULL, FALSE); callback_ref(cb); } else { callback_ref(cb); cb->li = listaddhead (lru_callback, cb); } cb->fid = callback_fid; hashtabadd (ht_callbacks, cb); mlog_log (MDEBROPA, "ropa_getcallback: added callback %x.%x.%x:%x", callback_fid.Volume, callback_fid.Vnode, callback_fid.Unique, host); } else { mlog_log (MDEBROPA, "ropa_getcallback: found callback %x.%x.%x:%x", callback_fid.Volume, callback_fid.Vnode, callback_fid.Unique, host); callback_ref(cb); } cc = add_client (cb, c); callback_deref (cb); update_callback (cc, callback, CBSHARED); debug_print_callbacks(); return 0; }
static struct ropa_client * client_query (uint32_t host, uint16_t port) { struct ropa_client *c, *c_new; int ret; c = client_query_notalkback(host, port); if (c == NULL) { interfaceAddr remote; struct rx_connection *conn = NULL; c = obtain_client(); assert (c->state == ROPAC_FREE && c->li == NULL); c->state = ROPAC_LOOKUP_U; c->flags |= ROPAF_LOOKUP; client_init (c, host, port, NULL, NULL); conn = rx_NewConnection (host, port, CM_SERVICE_ID, rxnull_NewClientSecurityObject(), 0); if (conn == NULL) { free(c); return NULL; } retry: switch (c->state) { case ROPAC_DEAD: c->li = listaddtail (lru_clients, c); ret = ENETDOWN; break; case ROPAC_LOOKUP_U: ret = RXAFSCB_WhoAreYou (conn, &remote); if (ret == RXGEN_OPCODE) { c->state = ROPAC_LOOKUP; goto retry; } else if (ret == RX_CALL_DEAD) { c->state = ROPAC_DEAD; goto retry; } else { struct ropa_client ckey; ckey.uuid = remote.uuid; c_new = hashtabsearch (ht_clients_uuid, &ckey); if (c_new == NULL) { client_init (c, host, port, &remote.uuid, NULL); ret = RXAFSCB_InitCallBackState3(conn, &server_uuid); } else { client_update_interfaces (c_new, host, port, &remote); disconnect_client (c); c = c_new; listdel(lru_clients, c->li); c->li = NULL; } } break; case ROPAC_LOOKUP: { afsUUID uuid; ret = RXAFSCB_InitCallBackState(conn); if (ret == RX_CALL_DEAD) { c->state = ROPAC_DEAD; goto retry; } uuid_init_simple (&uuid, host); client_init (c, host, port, &uuid, NULL); break; } default: exit(-1); } rx_DestroyConnection (conn); if ((c->flags & ROPAF_WAITING) != 0) LWP_NoYieldSignal (c); c->flags &= ~(ROPAF_LOOKUP|ROPAF_WAITING); if (ret) { assert (c->li != NULL); return NULL; } assert (c->li == NULL); c->li = listaddhead (lru_clients, c); } else { /* c != NULL */ if ((c->flags & ROPAF_LOOKUP) != 0) { c->flags |= ROPAF_WAITING; LWP_WaitProcess (c); } assert (c->li != NULL); } return c; }