list: add iteration with a cursor

Iterating a list with a cursor is heavier but is safe against removal
of any element in the list. Move the hook cursor iterator to list.
This commit is contained in:
Wim Taymans 2018-08-15 11:17:12 +02:00
parent ce4232cbc7
commit 5fe230e5ff
2 changed files with 19 additions and 11 deletions

View file

@ -89,16 +89,11 @@ static inline void spa_hook_remove(struct spa_hook *hook)
({ \
struct spa_hook_list *list = l; \
struct spa_list *s = start ? (struct spa_list *)start : &list->list; \
struct spa_hook cursor = { 0, }; \
struct spa_hook *ci; \
struct spa_hook cursor = { 0 }, *ci; \
int count = 0; \
spa_list_prepend(s, &cursor.link); \
for(ci = spa_list_first(&cursor.link, struct spa_hook, link); \
&ci->link != s; \
ci = spa_list_next(&cursor, link)) { \
spa_list_cursor_start(cursor, s, link); \
spa_list_for_each_cursor(ci, cursor, &list->list, link) { \
const type *cb = ci->funcs; \
spa_list_remove(&ci->link); \
spa_list_append(&cursor.link, &ci->link); \
if (cb && cb->version >= vers && cb->method) { \
cb->method(ci->data, ## __VA_ARGS__); \
count++; \
@ -106,7 +101,7 @@ static inline void spa_hook_remove(struct spa_hook *hook)
break; \
} \
} \
spa_list_remove(&cursor.link); \
spa_list_cursor_end(cursor, link); \
count; \
})

View file

@ -84,7 +84,7 @@ static inline void spa_list_remove(struct spa_list *elem)
pos = spa_list_next(pos, member))
#define spa_list_for_each(pos, head, member) \
spa_list_for_each_next(pos, head, head, member) \
spa_list_for_each_next(pos, head, head, member)
#define spa_list_for_each_safe_next(pos, tmp, head, curr, member) \
for (pos = spa_list_first(curr, __typeof__(*pos), member), \
@ -94,7 +94,20 @@ static inline void spa_list_remove(struct spa_list *elem)
tmp = spa_list_next(pos, member))
#define spa_list_for_each_safe(pos, tmp, head, member) \
spa_list_for_each_safe_next(pos, tmp, head, head, member) \
spa_list_for_each_safe_next(pos, tmp, head, head, member)
#define spa_list_cursor_start(cursor, head, member) \
spa_list_prepend(head, &(cursor).member)
#define spa_list_for_each_cursor(pos, cursor, head, member) \
for(pos = spa_list_first(&(cursor).member, __typeof__(*(pos)), member); \
spa_list_remove(&(pos)->member), \
spa_list_append(&(cursor).member, &(pos)->member), \
!spa_list_is_end(pos, head, member); \
pos = spa_list_next(&cursor, member))
#define spa_list_cursor_end(cursor, member) \
spa_list_remove(&(cursor).member)
#ifdef __cplusplus
} /* extern "C" */