summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 0f15d3b)
raw | patch | inline | side by side (parent: 0f15d3b)
author | Sebastian Harl <sh@tokkee.org> | |
Mon, 21 Apr 2014 16:52:48 +0000 (18:52 +0200) | ||
committer | Sebastian Harl <sh@tokkee.org> | |
Mon, 21 Apr 2014 16:52:48 +0000 (18:52 +0200) |
This function clears the list by removing all elements and releasing the
included objects. It's similar to destroy() but does not actually release the
list object itself.
included objects. It's similar to destroy() but does not actually release the
list object itself.
src/include/utils/llist.h | patch | blob | history | |
src/utils/llist.c | patch | blob | history | |
t/utils/llist_test.c | patch | blob | history |
index f557c9d41c63800ead40925f1414b7da02d80334..28816a6a49abaaf58232f55ab5b7e9a9f6a2ffa8 100644 (file)
void
sdb_llist_destroy(sdb_llist_t *list);
+/*
+ * sdb_llist_clear:
+ * Remove all elements from the list, releasing the included objects
+ * (decrement the ref-count).
+ */
+void
+sdb_llist_clear(sdb_llist_t *list);
+
/*
* sdb_llist_clone:
* Clone an existing list. The objects stored in the list will not be copied
diff --git a/src/utils/llist.c b/src/utils/llist.c
index e042c99df1c81bb3b55482f8a6b8b5470a20d388..f9bf722785dab30087c2c6e796858f3decd3f4a7 100644 (file)
--- a/src/utils/llist.c
+++ b/src/utils/llist.c
* private helper functions
*/
+static void
+llist_clear(sdb_llist_t *list)
+{
+ sdb_llist_elem_t *elem;
+
+ assert(list);
+ elem = list->head;
+ while (elem) {
+ sdb_llist_elem_t *tmp = elem->next;
+
+ sdb_object_deref(elem->obj);
+ free(elem);
+
+ elem = tmp;
+ }
+
+ list->head = list->tail = NULL;
+ list->length = 0;
+} /* llist_clear */
+
/* Insert a new element after 'elem'. If 'elem' is NULL, insert at the head of
* the list. */
static int
void
sdb_llist_destroy(sdb_llist_t *list)
{
- sdb_llist_elem_t *elem;
-
if (! list)
return;
pthread_rwlock_wrlock(&list->lock);
-
- elem = list->head;
- while (elem) {
- sdb_llist_elem_t *tmp = elem->next;
-
- sdb_object_deref(elem->obj);
- free(elem);
-
- elem = tmp;
- }
-
- list->head = list->tail = NULL;
- list->length = 0;
-
+ llist_clear(list);
pthread_rwlock_unlock(&list->lock);
pthread_rwlock_destroy(&list->lock);
free(list);
} /* sdb_llist_destroy */
+void
+sdb_llist_clear(sdb_llist_t *list)
+{
+ if (! list)
+ return;
+
+ pthread_rwlock_wrlock(&list->lock);
+ llist_clear(list);
+ pthread_rwlock_unlock(&list->lock);
+} /* sdb_llist_clear */
+
int
sdb_llist_append(sdb_llist_t *list, sdb_object_t *obj)
{
diff --git a/t/utils/llist_test.c b/t/utils/llist_test.c
index e8d366c2f103ccb244775c78bec7d5c9d2167ad5..cc9954d98662c76f89ef32f4e9416ea178073017 100644 (file)
--- a/t/utils/llist_test.c
+++ b/t/utils/llist_test.c
}
END_TEST
+START_TEST(test_clear)
+{
+ size_t i;
+ populate();
+ sdb_llist_clear(list);
+
+ for (i = 0; i < SDB_STATIC_ARRAY_LEN(golden_data); ++i) {
+ fail_unless(golden_data[i].ref_cnt == 1,
+ "sdb_llist_clear() did not deref element %s",
+ golden_data[i].name);
+ }
+
+ i = sdb_llist_len(list);
+ fail_unless(i == 0,
+ "sdb_llist_clear() left %zu elements in the list; "
+ "expected: 0", i);
+}
+END_TEST
+
START_TEST(test_append)
{
size_t i;
tcase_add_checked_fixture(tc, setup, teardown);
tcase_add_test(tc, test_clone);
tcase_add_test(tc, test_destroy);
+ tcase_add_test(tc, test_clear);
tcase_add_test(tc, test_append);
tcase_add_test(tc, test_insert);
tcase_add_test(tc, test_validate_insert);