libubox
C utility functions for OpenWrt.
safe_list.c
Go to the documentation of this file.
1 /*
2  * safe_list - linked list protected against recursive iteration with deletes
3  *
4  * Copyright (C) 2013 Felix Fietkau <nbd@openwrt.org>
5  *
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.
9  *
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.
17  */
18 
19 #include "safe_list.h"
20 
24  struct safe_list *next;
25 };
26 
27 static void
29  struct safe_list_iterator *i)
30 {
31  struct safe_list_iterator *next_i;
32  struct safe_list *next;
33 
34  next = list_entry(list->list.next, struct safe_list, list);
35  next_i = next->i;
36 
37  next->i = i;
38  i->next = next;
39  i->head = &next->i;
40 
41  i->next_i = next_i;
42  if (next_i)
43  next_i->head = &i->next_i;
44 }
45 
46 static void
48 {
49  *i->head = i->next_i;
50  if (i->next_i)
51  i->next_i->head = i->head;
52 }
53 
54 static void
56  struct safe_list_iterator *i)
57 {
60 }
61 
62 int safe_list_for_each(struct safe_list *head,
63  int (*cb)(void *ctx, struct safe_list *list),
64  void *ctx)
65 {
66  struct safe_list_iterator i;
67  struct safe_list *cur;
68  int ret = 0;
69 
70  for (cur = list_entry(head->list.next, struct safe_list, list),
72  cur != head;
73  cur = i.next, __safe_list_move_iterator(cur, &i)) {
74  ret = cb(ctx, cur);
75  if (ret)
76  break;
77  }
78 
80  return ret;
81 }
82 
83 void safe_list_add(struct safe_list *list, struct safe_list *head)
84 {
85  list->i = NULL;
86  list_add_tail(&list->list, &head->list);
87 }
88 
89 void safe_list_add_first(struct safe_list *list, struct safe_list *head)
90 {
91  list->i = NULL;
92  list_add(&list->list, &head->list);
93 }
94 
96 {
97  struct safe_list_iterator *i, *next_i, **tail;
98  struct safe_list *next;
99 
100  next = list_entry(list->list.next, struct safe_list, list);
101  list_del(&list->list);
102 
103  if (!list->i)
104  return;
105 
106  next_i = next->i;
107  tail = &next->i;
108 
109  for (i = list->i; i; i = i->next_i) {
110  tail = &i->next_i;
111  i->next = next;
112  }
113 
114  next->i = list->i;
115  list->i->head = &next->i;
116  *tail = next_i;
117  if (next_i)
118  next_i->head = tail;
119 
120  list->i = NULL;
121 }
static void list_add_tail(struct list_head *_new, struct list_head *head)
Definition: list.h:165
static void list_add(struct list_head *_new, struct list_head *head)
Definition: list.h:159
static void list_del(struct list_head *entry)
Definition: list.h:96
#define list_entry(ptr, type, field)
Definition: list.h:120
int safe_list_for_each(struct safe_list *head, int(*cb)(void *ctx, struct safe_list *list), void *ctx)
Definition: safe_list.c:62
void safe_list_add(struct safe_list *list, struct safe_list *head)
Definition: safe_list.c:83
static void __safe_list_del_iterator(struct safe_list_iterator *i)
Definition: safe_list.c:47
static void __safe_list_set_iterator(struct safe_list *list, struct safe_list_iterator *i)
Definition: safe_list.c:28
void safe_list_add_first(struct safe_list *list, struct safe_list *head)
Definition: safe_list.c:89
void safe_list_del(struct safe_list *list)
Definition: safe_list.c:95
static void __safe_list_move_iterator(struct safe_list *list, struct safe_list_iterator *i)
Definition: safe_list.c:55
struct list_head * next
Definition: list.h:54
struct safe_list_iterator ** head
Definition: safe_list.c:22
struct safe_list_iterator * next_i
Definition: safe_list.c:23
struct safe_list * next
Definition: safe_list.c:24
struct list_head list
Definition: safe_list.h:36
struct safe_list_iterator * i
Definition: safe_list.h:37