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.
20 * Use this linked list implementation as a replacement for list.h if you
21 * want to allow deleting arbitrary list entries from within one or more
22 * recursive iterator calling context
25 #ifndef __LIBUBOX_SAFE_LIST_H
26 #define __LIBUBOX_SAFE_LIST_H
33 struct safe_list_iterator
;
36 struct list_head list
;
37 struct safe_list_iterator
*i
;
40 int safe_list_for_each(struct safe_list
*list
,
41 int (*cb
)(void *ctx
, struct safe_list
*list
),
44 void safe_list_add(struct safe_list
*list
, struct safe_list
*head
);
45 void safe_list_del(struct safe_list
*list
);
47 #define INIT_SAFE_LIST(_head) \
49 INIT_LIST_HEAD(_head.list); \
53 #define SAFE_LIST_INIT(_name) { LIST_HEAD_INIT(_name.list), NULL }
54 #define SAFE_LIST(_name) struct safe_list _name = SAFE_LIST_INIT(_name)
56 static inline bool safe_list_empty(struct safe_list
*head
)
58 return list_empty(&head
->list
);