/* * BIRD Library -- Safe Linked Lists * * (c) 1998 Martin Mares * * Can be freely distributed and used under the terms of the GNU GPL. */ #define _BIRD_SLISTS_C_ #include "nest/bird.h" #include "lib/slists.h" static inline void s_merge(snode *from, snode *to) { siterator *f, *g; if (!(f = from->readers)) return; if (!(g = to->readers)) { /* Fast path */ to->readers = f; f->prev = (siterator *) to; fixup: while (f && f->node) { f->node = NULL; f = f->next; } return; } /* Really merging */ while (g->next) g = g->next; g->next = f; f->prev = g; goto fixup; } snode * s_get(siterator *i) { siterator *f, *g; snode *n; if (!(n = i->node)) { /* * No node found. We have to walk the iterator list backwards * to find where are we linked. */ f = i; while (!f->null) f = f->prev; n = (snode *) f; } f = i->prev; /* Maybe the snode itself */ g = i->next; f->next = g; if (g) g->prev = f; i->prev = NULL; i->next = NULL; return n; } void s_put(siterator *i, snode *n) { siterator *f; i->node = n; if (f = n->readers) f->prev = i; i->next = f; n->readers = i; i->prev = (siterator *) n; i->null = NULL; } void s_add_tail(slist *l, snode *n) { snode *z = l->tail; n->next = (snode *) &l->null; n->prev = z; z->next = n; l->tail = n; n->readers = NULL; } void s_add_head(slist *l, snode *n) { snode *z = l->head; n->next = z; n->prev = (snode *) &l->head; z->prev = n; l->head = n; n->readers = NULL; } void s_insert_node(snode *n, snode *after) { snode *z = after->next; n->next = z; n->prev = after; after->next = n; z->prev = n; n->readers = NULL; } void s_rem_node(snode *n) { snode *z = n->prev; snode *x = n->next; z->next = x; x->prev = z; s_merge(n, x); } void s_init_list(slist *l) { l->head = (snode *) &l->null; l->null = NULL; l->tail = (snode *) &l->head; l->tail_readers = NULL; } void s_add_tail_list(slist *to, slist *l) { snode *p = to->tail; snode *q = l->head; p->next = q; q->prev = p; q = l->tail; q->next = (snode *) &to->null; to->tail = q; s_merge((snode *) &l->null, (snode *) &to->null); }