Commit ec8654d9 authored by Rusty Russell's avatar Rusty Russell

list_del_init/list_node_init: for multiple list_del() calls.

Signed-off-by: default avatarRusty Russell <rusty@rustcorp.com.au>
parent a7b28faf
......@@ -145,6 +145,18 @@ static inline void list_head_init(struct list_head *h)
h->n.next = h->n.prev = &h->n;
}
/**
* list_node_init - initialize a list_node
* @n: the list_node to link to itself.
*
* You don't need to use this normally! But it lets you list_del(@n)
* safely.
*/
static inline void list_node_init(struct list_node *n)
{
n->next = n->prev = n;
}
/**
* list_add - add an entry at the start of a linked list.
* @h: the list_head to add the node to
......@@ -237,7 +249,7 @@ static inline bool list_empty_nodebug(const struct list_head *h)
* another list, but not deleted again.
*
* See also:
* list_del_from()
* list_del_from(), list_del_init()
*
* Example:
* list_del(&child->list);
......@@ -255,6 +267,27 @@ static inline void list_del_(struct list_node *n, const char* abortstr)
#endif
}
/**
* list_del_init - delete a node, and reset it so it can be deleted again.
* @n: the list_node to be deleted.
*
* list_del(@n) or list_del_init() again after this will be safe,
* which can be useful in some cases.
*
* See also:
* list_del_from(), list_del()
*
* Example:
* list_del_init(&child->list);
* parent->num_children--;
*/
#define list_del_init(n) list_del_init_(n, LIST_LOC)
static inline void list_del_init_(struct list_node *n, const char *abortstr)
{
list_del_(n, abortstr);
list_node_init(n);
}
/**
* list_del_from - delete an entry from a known linked list.
* @h: the list_head the node is in.
......
......@@ -25,7 +25,7 @@ int main(int argc, char *argv[])
opaque_t *q, *nq;
struct list_head opaque_list = LIST_HEAD_INIT(opaque_list);
plan_tests(68);
plan_tests(70);
/* Test LIST_HEAD, LIST_HEAD_INIT, list_empty and check_list */
ok1(list_empty(&static_list));
ok1(list_check(&static_list, NULL));
......@@ -155,6 +155,19 @@ int main(int argc, char *argv[])
ok1(i == 3);
ok1(list_empty(&parent.children));
/* Test list_node_init: safe to list_del after this. */
list_node_init(&c->list);
list_del(&c->list);
/* Test list_del_init */
list_add(&parent.children, &c->list);
ok1(!list_empty(&parent.children));
list_del_init(&c->list);
ok1(list_empty(&parent.children));
/* We can call this as many times as we like. */
list_del_init(&c->list);
list_del_init(&c->list);
/* Test list_for_each_off. */
list_add_tail(&opaque_list,
(struct list_node *)create_opaque_blob());
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment