2 * safe_list - linked list protected against recursive iteration with deletes
4 * Copyright (C) 2013 Felix Fietkau <nbd@openwrt.org>
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 #include "safe_list.h"
21 struct safe_list_iterator
{
22 struct safe_list_iterator
**head
;
23 struct safe_list_iterator
*next_i
;
24 struct safe_list
*next
;
28 __safe_list_set_iterator(struct safe_list
*list
,
29 struct safe_list_iterator
*i
)
31 struct safe_list_iterator
*next_i
;
32 struct safe_list
*next
;
34 next
= list_entry(list
->list
.next
, struct safe_list
, list
);
43 next_i
->head
= &i
->next_i
;
47 __safe_list_del_iterator(struct safe_list_iterator
*i
)
51 i
->next_i
->head
= i
->head
;
55 __safe_list_move_iterator(struct safe_list
*list
,
56 struct safe_list_iterator
*i
)
58 __safe_list_del_iterator(i
);
59 __safe_list_set_iterator(list
, i
);
62 int safe_list_for_each(struct safe_list
*head
,
63 int (*cb
)(void *ctx
, struct safe_list
*list
),
66 struct safe_list_iterator i
;
67 struct safe_list
*cur
;
70 for (cur
= list_entry(head
->list
.next
, struct safe_list
, list
),
71 __safe_list_set_iterator(cur
, &i
);
73 cur
= i
.next
, __safe_list_move_iterator(cur
, &i
)) {
79 __safe_list_del_iterator(&i
);
83 void safe_list_add(struct safe_list
*list
, struct safe_list
*head
)
86 list_add_tail(&list
->list
, &head
->list
);
89 void safe_list_add_first(struct safe_list
*list
, struct safe_list
*head
)
92 list_add(&list
->list
, &head
->list
);
95 void safe_list_del(struct safe_list
*list
)
97 struct safe_list_iterator
*i
, *next_i
, **tail
;
98 struct safe_list
*next
;
100 next
= list_entry(list
->list
.next
, struct safe_list
, list
);
101 list_del(&list
->list
);
109 for (i
= list
->i
; i
; i
= i
->next_i
) {
115 list
->i
->head
= &next
->i
;