for (_iter = fr_dlist_head(_list_head), \
_tmp = fr_dlist_head(_list_head) ? *fr_dlist_item_to_entry((_list_head)->offset, fr_dlist_head(_list_head)) : (fr_dlist_t){ .prev = NULL, .next = NULL }; \
_iter; \
- _iter = _tmp.next ? fr_dlist_entry_to_item((_list_head)->offset, _tmp.next) : NULL, \
- _tmp = _tmp.next ? *_tmp.next : (fr_dlist_t){ .prev = NULL, .next = NULL })
+ _iter = _tmp.next && (_tmp.next != &(_list_head)->entry) ? fr_dlist_entry_to_item((_list_head)->offset, _tmp.next) : NULL, \
+ _tmp = _tmp.next && (_tmp.next != &(_list_head)->entry) ? *_tmp.next : (fr_dlist_t){ .prev = NULL, .next = NULL })
/** Find the dlist pointers within a list item
TEST_CHECK(a2.entry.prev == &a1.entry);
}
+static void test_dlist_foreach_safe(void)
+{
+ dlist_test_item_t a1 = { .id = "a1" };
+ dlist_test_item_t a2 = { .id = "a2" };
+ dlist_test_item_t a3 = { .id = "a3" };
+
+ fr_dlist_head_t head;
+ unsigned int count = 0;
+
+ fr_dlist_init(&head, dlist_test_item_t, entry);
+
+ fr_dlist_insert_tail(&head, &a1);
+ fr_dlist_insert_tail(&head, &a2);
+ fr_dlist_insert_tail(&head, &a3);
+
+ fr_dlist_foreach_safe(&head, dlist_test_item_t, i) {
+ fr_dlist_remove(&head, i);
+ count++;
+ }}
+
+ TEST_CHECK_RET((int)count, (int)3);
+}
+
TEST_LIST = {
/*
* Allocation and management
*/
{ "fr_dlist_move", test_dlist_move },
{ "fr_dlist_entry_move", test_dlist_entry_move },
-
+ { "fr_dlist_foreach_safe", test_dlist_foreach_safe },
{ NULL }
};