X-Git-Url: https://git.tokkee.org/?p=sysdb.git;a=blobdiff_plain;f=src%2Futils%2Fllist.c;h=f9bf722785dab30087c2c6e796858f3decd3f4a7;hp=2dc7781cccab7f2ca8decd373461ae7e42999d0b;hb=56b97a180a53aecbfe9f7162b8ece3faae973cf9;hpb=39a45905e0b237e458b1826ff9b4fad1c4a59550 diff --git a/src/utils/llist.c b/src/utils/llist.c index 2dc7781..f9bf722 100644 --- a/src/utils/llist.c +++ b/src/utils/llist.c @@ -69,10 +69,30 @@ struct sdb_llist_iter { * 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 -sdb_llist_insert_after(sdb_llist_t *list, sdb_llist_elem_t *elem, +llist_insert_after(sdb_llist_t *list, sdb_llist_elem_t *elem, sdb_object_t *obj) { sdb_llist_elem_t *new; @@ -117,7 +137,7 @@ sdb_llist_insert_after(sdb_llist_t *list, sdb_llist_elem_t *elem, sdb_object_ref(obj); ++list->length; return 0; -} /* sdb_llist_insert_after */ +} /* llist_insert_after */ static sdb_llist_elem_t * llist_search(sdb_llist_t *list, @@ -134,7 +154,7 @@ llist_search(sdb_llist_t *list, } /* llist_search */ static sdb_object_t * -sdb_llist_remove_elem(sdb_llist_t *list, sdb_llist_elem_t *elem) +llist_remove_elem(sdb_llist_t *list, sdb_llist_elem_t *elem) { sdb_object_t *obj; @@ -161,7 +181,7 @@ sdb_llist_remove_elem(sdb_llist_t *list, sdb_llist_elem_t *elem) --list->length; return obj; -} /* sdb_llist_remove_elem */ +} /* llist_remove_elem */ /* * public API @@ -213,31 +233,27 @@ sdb_llist_clone(sdb_llist_t *list) 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) { @@ -247,7 +263,7 @@ sdb_llist_append(sdb_llist_t *list, sdb_object_t *obj) return -1; pthread_rwlock_wrlock(&list->lock); - status = sdb_llist_insert_after(list, list->tail, obj); + status = llist_insert_after(list, list->tail, obj); pthread_rwlock_unlock(&list->lock); return status; } /* sdb_llist_append */ @@ -274,7 +290,7 @@ sdb_llist_insert(sdb_llist_t *list, sdb_object_t *obj, size_t idx) prev = next; next = next->next; } - status = sdb_llist_insert_after(list, prev, obj); + status = llist_insert_after(list, prev, obj); pthread_rwlock_unlock(&list->lock); return status; } /* sdb_llist_insert */ @@ -303,7 +319,7 @@ sdb_llist_insert_sorted(sdb_llist_t *list, prev = next; next = next->next; } - status = sdb_llist_insert_after(list, prev, obj); + status = llist_insert_after(list, prev, obj); pthread_rwlock_unlock(&list->lock); return status; } /* sdb_llist_insert_sorted */ @@ -321,6 +337,7 @@ sdb_llist_get(sdb_llist_t *list, size_t i) /* iterate */; assert(elem); + sdb_object_ref(elem->obj); return elem->obj; } /* sdb_llist_get */ @@ -376,12 +393,35 @@ sdb_llist_remove(sdb_llist_t *list, pthread_rwlock_wrlock(&list->lock); elem = llist_search(list, lookup, user_data); if (elem) - obj = sdb_llist_remove_elem(list, elem); + obj = llist_remove_elem(list, elem); pthread_rwlock_unlock(&list->lock); return obj; } /* sdb_llist_remove */ +sdb_object_t * +sdb_llist_remove_by_name(sdb_llist_t *list, const char *key) +{ + sdb_llist_elem_t *elem; + sdb_object_t *obj = NULL; + + if (! list) + return NULL; + + pthread_rwlock_rdlock(&list->lock); + + for (elem = list->head; elem; elem = elem->next) + if ((key == elem->obj->name) + || (! strcasecmp(elem->obj->name, key))) + break; + + if (elem) + obj = llist_remove_elem(list, elem); + pthread_rwlock_unlock(&list->lock); + + return obj; +} /* sdb_llist_remove_by_name */ + sdb_object_t * sdb_llist_shift(sdb_llist_t *list) { @@ -391,7 +431,7 @@ sdb_llist_shift(sdb_llist_t *list) return NULL; pthread_rwlock_wrlock(&list->lock); - obj = sdb_llist_remove_elem(list, list->head); + obj = llist_remove_elem(list, list->head); pthread_rwlock_unlock(&list->lock); return obj; } /* sdb_llist_shift */ @@ -474,7 +514,7 @@ sdb_llist_iter_remove_current(sdb_llist_iter_t *iter) else elem = iter->elem->prev; if (elem) - sdb_llist_remove_elem(iter->list, elem); + llist_remove_elem(iter->list, elem); pthread_rwlock_unlock(&iter->list->lock);