LIST *listdelnth(LIST * head, int nth, freefunc func) { LIST *item, *elt; int i; if (!head || nth < 0) return NULL; if (nth == 0) { elt = head; head = head->next; listdel(NULL, elt, func); return head; } for (i = 0, item = head; item && item->next && i < nth - 1; item = item->next, i++) ; if (item && item->next) { elt = item->next; item->next = elt->next; listdel(NULL, elt, func); } return head; }
static void disconnect_client (struct ropa_client *c) { int ret; int i; assert (c->ref == 0); if (c->li) { listdel (lru_clients, c->li); c->li = NULL; } for (i = 0 ; i < c->numberOfInterfaces ; i++) { int ret = hashtabdel (ht_clients_ip, &c->addr[i]); assert (ret == 0); clear_addr (&c->addr[i]); } c->numberOfInterfaces = 0; c->port = 0; c->state = ROPAC_FREE; ret = hashtabdel (ht_clients_uuid, c); assert (ret == 0); c->li = listaddtail (lru_clients, c); }
static void re_probe (ConnCacheEntry *e) { Listitem *item; struct timeval tv; assert (e->probe != NULL); gettimeofday (&tv, NULL); if (e->probe_le) { listdel (connprobelist, e->probe_le); e->probe_next = min(tv.tv_sec + (1 << e->ntries), e->probe_next); } else e->probe_next = tv.tv_sec + (1 << e->ntries); if (e->ntries <= MAX_RETRIES) ++e->ntries; for (item = listhead (connprobelist); item; item = listnext (connprobelist, item)) { ConnCacheEntry *this = (ConnCacheEntry *)listdata (item); if (e->probe_next < this->probe_next) { e->probe_le = listaddbefore (connprobelist, item, e); LWP_NoYieldSignal (connprobelist); return; } } e->probe_le = listaddtail (connprobelist, e); LWP_NoYieldSignal (connprobelist); }
int main() { int i, di; ELemType e, de; linklist *L = (linklist *)malloc(sizeof(linklist)); if (!L) return ERROR; printf("creat a linklist\n"); CreatList(L); printf("L = %d \n", L->next->data); display(L); //linklist *m; // m = L; //display(L); reverse(L); display(L); printf("please input the insert lo & elem:\n"); scanf("%d %d", &i, &e); listinsert(L, i, e); printf("please input the del number:\n"); scanf("%d", &di); listdel(L, di, &de); display(L); free(L); return 0; }
void mnode_free (struct mnode *node, Bool bad) { if (node->li) listdel (mnode_lru, node->li); /* bad -> reread 0 -> close */ if (bad) { if (node->flags.fdp) close (node->fd); memset (&node->flags, 0, sizeof (node->flags)); } if (--node->ref == 0) { if (node->flags.fdp) { close (node->fd); node->flags.fdp = FALSE; } if (node->flags.removedp == TRUE) { hashtabdel (mnode_htab, node); node->flags.removedp = FALSE; } mnode_numfree++; node->li = listaddtail (mnode_lru, node); } else node->li = listaddhead (mnode_lru, node); }
static void client_ref (struct ropa_client *c) { assert (c->ref >= 0); if (c->li) listdel (lru_clients, c->li); c->ref++; if (c->li) c->li = listaddhead (lru_clients, c); }
static void break_ccpair (struct ropa_ccpair *cc, Bool notify_clientp) { AFSCBFids fids; AFSCBs cbs; int ret; debug_print_callbacks(); cc->expire = 0; if (cc->li) listdel (lru_ccpair, cc->li); if (notify_clientp) { fids.len = 1; fids.val = &cc->cb->fid; cbs.len = 0; notify_client (cc->client, &fids, &cbs); } if (cc->cb_li) { listdel (cc->cb->ccpairs, cc->cb_li); cc->cb_li = NULL; } /* The reverse of these are in add_client */ ret = hashtabdel (ht_ccpairs, cc); assert (ret == 0); client_deref (cc->client); cc->client = NULL; callback_deref (cc->cb); cc->cb = NULL; heap_remove (heap_ccpairs, cc->heap); cc->li = listaddtail (lru_ccpair, cc); debug_print_callbacks(); }
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 void callback_ref (struct ropa_cb *cb) { assert (cb->ref >= 0); if (cb->li) listdel (lru_callback, cb->li); cb->ref++; mlog_log (MDEBROPA, "cb_ref: %x.%x.%x (%d)", cb->fid.Volume, cb->fid.Vnode, cb->fid.Unique, cb->ref); if (cb->li) cb->li = listaddhead (lru_callback, cb); }
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 * obtain_client (void) { struct ropa_client *c; c = listdeltail (lru_clients); DIAGNOSTIC_CHECK_CLIENT(c); c->li = NULL; if (client_inuse_p (c)) break_client (c, TRUE); if (c->li) { listdel(lru_clients, c->li); c->li = NULL; } return c; }
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; } }
static void recycle_conn (ConnCacheEntry *e) { assert (e->refcount == 0); if (e->parent != NULL) { conn_free (e->parent); e->parent = NULL; } if (e->probe_le != NULL) { listdel (connprobelist, e->probe_le); e->probe_le = NULL; } if (!e->flags.killme) hashtabdel (connhtab, e); rx_DestroyConnection (e->connection); memset (e, 0, sizeof(*e)); listaddhead (connfreelist, e); --nactive_connections; }
static void callback_deref (struct ropa_cb *cb) { cb->ref--; mlog_log (MDEBROPA, "cb_deref: %x.%x.%x (%d)", cb->fid.Volume, cb->fid.Vnode, cb->fid.Unique, cb->ref); if (cb->ref == 0) { int ret = hashtabdel (ht_callbacks, cb); mlog_log (MDEBROPA, "cb_deref: removing %x.%x.%x", cb->fid.Volume, cb->fid.Vnode, cb->fid.Unique); assert (ret == 0); if (cb->li) listdel (lru_callback, cb->li); assert (listemptyp (cb->ccpairs)); memset (&cb->fid, 0, sizeof(cb->fid)); cb->li = listaddtail (lru_callback, cb); } }
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; }
static void pinger (char *arg) { for (;;) { struct timeval tv; Listitem *item; ConnCacheEntry *e; struct in_addr addr; const char *port_str; arla_warnx(ADEBCONN, "running pinger"); while (listemptyp (connprobelist)) LWP_WaitProcess (connprobelist); item = listhead (connprobelist); e = (ConnCacheEntry *)listdata (item); assert (e->probe_le == item); gettimeofday (&tv, NULL); if (tv.tv_sec < e->probe_next) { unsigned long t = e->probe_next - tv.tv_sec; arla_warnx(ADEBCONN, "pinger: sleeping %lu second(s)", t); IOMGR_Sleep (t); continue; } listdel (connprobelist, item); e->probe_le = NULL; if (e->flags.alivep) continue; addr.s_addr = e->host; port_str = ports_num2name (e->port); if (port_str != NULL) arla_warnx (ADEBCONN, "pinger: probing %s/%s", inet_ntoa(addr), port_str); else arla_warnx (ADEBCONN, "pinger: probing %s/%d", inet_ntoa(addr), e->port); ++e->refcount; if (e->probe == NULL) arla_warnx(ADEBWARN, "pinger: probe function is NULL, " "host: %s cell: %d port: %d", inet_ntoa(addr), e->cell, e->port); if (connected_mode == DISCONNECTED) { arla_warnx(ADEBCONN, "pinger: ignoring host in disconnected mode"); } else if (e->probe && ((*(e->probe))(e->connection) == 0)) { conn_alive (e); } else { re_probe (e); } conn_free (e); } }