summaryrefslogtreecommitdiff
path: root/nss/lib/base/list.c
diff options
context:
space:
mode:
Diffstat (limited to 'nss/lib/base/list.c')
-rw-r--r--nss/lib/base/list.c263
1 files changed, 134 insertions, 129 deletions
diff --git a/nss/lib/base/list.c b/nss/lib/base/list.c
index 5f34923..e798cf0 100644
--- a/nss/lib/base/list.c
+++ b/nss/lib/base/list.c
@@ -13,19 +13,19 @@
#endif /* BASE_H */
struct nssListElementStr {
- PRCList link;
- void *data;
+ PRCList link;
+ void *data;
};
typedef struct nssListElementStr nssListElement;
struct nssListStr {
- NSSArena *arena;
- PZLock *lock;
+ NSSArena *arena;
+ PZLock *lock;
nssListElement *head;
- PRUint32 count;
+ PRUint32 count;
nssListCompareFunc compareFunc;
- nssListSortFunc sortFunc;
+ nssListSortFunc sortFunc;
PRBool i_alloced_arena;
};
@@ -36,10 +36,12 @@ struct nssListIteratorStr {
};
#define NSSLIST_LOCK_IF(list) \
- if ((list)->lock) PZ_Lock((list)->lock)
+ if ((list)->lock) \
+ PZ_Lock((list)->lock)
#define NSSLIST_UNLOCK_IF(list) \
- if ((list)->lock) PZ_Unlock((list)->lock)
+ if ((list)->lock) \
+ PZ_Unlock((list)->lock)
static PRBool
pointer_compare(void *a, void *b)
@@ -50,65 +52,58 @@ pointer_compare(void *a, void *b)
static nssListElement *
nsslist_get_matching_element(nssList *list, void *data)
{
- PRCList *link;
nssListElement *node;
node = list->head;
if (!node) {
- return NULL;
+ return NULL;
}
- link = &node->link;
while (node) {
- /* using a callback slows things down when it's just compare ... */
- if (list->compareFunc(node->data, data)) {
- break;
- }
- link = &node->link;
- if (link == PR_LIST_TAIL(&list->head->link)) {
- node = NULL;
- break;
- }
- node = (nssListElement *)PR_NEXT_LINK(&node->link);
+ /* using a callback slows things down when it's just compare ... */
+ if (list->compareFunc(node->data, data)) {
+ break;
+ }
+ if (&node->link == PR_LIST_TAIL(&list->head->link)) {
+ node = NULL;
+ break;
+ }
+ node = (nssListElement *)PR_NEXT_LINK(&node->link);
}
return node;
}
NSS_IMPLEMENT nssList *
-nssList_Create
-(
- NSSArena *arenaOpt,
- PRBool threadSafe
-)
+nssList_Create(NSSArena *arenaOpt, PRBool threadSafe)
{
NSSArena *arena;
nssList *list;
PRBool i_alloced;
if (arenaOpt) {
- arena = arenaOpt;
- i_alloced = PR_FALSE;
+ arena = arenaOpt;
+ i_alloced = PR_FALSE;
} else {
- arena = nssArena_Create();
- i_alloced = PR_TRUE;
+ arena = nssArena_Create();
+ i_alloced = PR_TRUE;
}
if (!arena) {
- return (nssList *)NULL;
+ return (nssList *)NULL;
}
list = nss_ZNEW(arena, nssList);
if (!list) {
- if (!arenaOpt) {
- NSSArena_Destroy(arena);
- }
- return (nssList *)NULL;
+ if (!arenaOpt) {
+ NSSArena_Destroy(arena);
+ }
+ return (nssList *)NULL;
}
if (threadSafe) {
- list->lock = PZ_NewLock(nssILockOther);
- if (!list->lock) {
- if (arenaOpt) {
- nss_ZFreeIf(list);
- } else {
- NSSArena_Destroy(arena);
- }
- return (nssList *)NULL;
- }
+ list->lock = PZ_NewLock(nssILockOther);
+ if (!list->lock) {
+ if (arenaOpt) {
+ nss_ZFreeIf(list);
+ } else {
+ NSSArena_Destroy(arena);
+ }
+ return (nssList *)NULL;
+ }
}
list->arena = arena;
list->i_alloced_arena = i_alloced;
@@ -119,15 +114,18 @@ nssList_Create
NSS_IMPLEMENT PRStatus
nssList_Destroy(nssList *list)
{
+ if (!list) {
+ return PR_SUCCESS;
+ }
if (!list->i_alloced_arena) {
- nssList_Clear(list, NULL);
+ nssList_Clear(list, NULL);
}
if (list->lock) {
- (void)PZ_DestroyLock(list->lock);
+ (void)PZ_DestroyLock(list->lock);
}
if (list->i_alloced_arena) {
- NSSArena_Destroy(list->arena);
- list = NULL;
+ NSSArena_Destroy(list->arena);
+ list = NULL;
}
nss_ZFreeIf(list);
return PR_SUCCESS;
@@ -157,17 +155,21 @@ nssList_Clear(nssList *list, nssListElementDestructorFunc destructor)
{
PRCList *link;
nssListElement *node, *tmp;
+ if (!list) {
+ return;
+ }
NSSLIST_LOCK_IF(list);
node = list->head;
list->head = NULL;
while (node && list->count > 0) {
- if (destructor) (*destructor)(node->data);
- link = &node->link;
- tmp = (nssListElement *)PR_NEXT_LINK(link);
- PR_REMOVE_LINK(link);
- nss_ZFreeIf(node);
- node = tmp;
- --list->count;
+ if (destructor)
+ (*destructor)(node->data);
+ link = &node->link;
+ tmp = (nssListElement *)PR_NEXT_LINK(link);
+ PR_REMOVE_LINK(link);
+ nss_ZFreeIf(node);
+ node = tmp;
+ --list->count;
}
NSSLIST_UNLOCK_IF(list);
}
@@ -177,38 +179,39 @@ nsslist_add_element(nssList *list, void *data)
{
nssListElement *node = nss_ZNEW(list->arena, nssListElement);
if (!node) {
- return PR_FAILURE;
+ return PR_FAILURE;
}
PR_INIT_CLIST(&node->link);
node->data = data;
if (list->head) {
- if (list->sortFunc) {
- PRCList *link;
- nssListElement *currNode;
- currNode = list->head;
- /* insert in ordered list */
- while (currNode) {
- link = &currNode->link;
- if (list->sortFunc(data, currNode->data) <= 0) {
- /* new element goes before current node */
- PR_INSERT_BEFORE(&node->link, link);
- /* reset head if this is first */
- if (currNode == list->head) list->head = node;
- break;
- }
- if (link == PR_LIST_TAIL(&list->head->link)) {
- /* reached end of list, append */
- PR_INSERT_AFTER(&node->link, link);
- break;
- }
- currNode = (nssListElement *)PR_NEXT_LINK(&currNode->link);
- }
- } else {
- /* not sorting */
- PR_APPEND_LINK(&node->link, &list->head->link);
- }
+ if (list->sortFunc) {
+ PRCList *link;
+ nssListElement *currNode;
+ currNode = list->head;
+ /* insert in ordered list */
+ while (currNode) {
+ link = &currNode->link;
+ if (list->sortFunc(data, currNode->data) <= 0) {
+ /* new element goes before current node */
+ PR_INSERT_BEFORE(&node->link, link);
+ /* reset head if this is first */
+ if (currNode == list->head)
+ list->head = node;
+ break;
+ }
+ if (link == PR_LIST_TAIL(&list->head->link)) {
+ /* reached end of list, append */
+ PR_INSERT_AFTER(&node->link, link);
+ break;
+ }
+ currNode = (nssListElement *)PR_NEXT_LINK(&currNode->link);
+ }
+ } else {
+ /* not sorting */
+ PR_APPEND_LINK(&node->link, &list->head->link);
+ }
} else {
- list->head = node;
+ list->head = node;
}
++list->count;
return PR_SUCCESS;
@@ -231,9 +234,9 @@ nssList_AddUnique(nssList *list, void *data)
NSSLIST_LOCK_IF(list);
node = nsslist_get_matching_element(list, data);
if (node) {
- /* already in, finish */
- NSSLIST_UNLOCK_IF(list);
- return PR_SUCCESS;
+ /* already in, finish */
+ NSSLIST_UNLOCK_IF(list);
+ return PR_SUCCESS;
}
nssrv = nsslist_add_element(list, data);
NSSLIST_UNLOCK_IF(list);
@@ -247,14 +250,14 @@ nssList_Remove(nssList *list, void *data)
NSSLIST_LOCK_IF(list);
node = nsslist_get_matching_element(list, data);
if (node) {
- if (node == list->head) {
- list->head = (nssListElement *)PR_NEXT_LINK(&node->link);
- }
- PR_REMOVE_LINK(&node->link);
- nss_ZFreeIf(node);
- if (--list->count == 0) {
- list->head = NULL;
- }
+ if (node == list->head) {
+ list->head = (nssListElement *)PR_NEXT_LINK(&node->link);
+ }
+ PR_REMOVE_LINK(&node->link);
+ nss_ZFreeIf(node);
+ if (--list->count == 0) {
+ list->head = NULL;
+ }
}
NSSLIST_UNLOCK_IF(list);
return PR_SUCCESS;
@@ -284,16 +287,17 @@ nssList_GetArray(nssList *list, void **rvArray, PRUint32 maxElements)
PR_ASSERT(maxElements > 0);
node = list->head;
if (!node) {
- return PR_SUCCESS;
+ return PR_SUCCESS;
}
NSSLIST_LOCK_IF(list);
while (node) {
- rvArray[i++] = node->data;
- if (i == maxElements) break;
- node = (nssListElement *)PR_NEXT_LINK(&node->link);
- if (node == list->head) {
- break;
- }
+ rvArray[i++] = node->data;
+ if (i == maxElements)
+ break;
+ node = (nssListElement *)PR_NEXT_LINK(&node->link);
+ if (node == list->head) {
+ break;
+ }
}
NSSLIST_UNLOCK_IF(list);
return PR_SUCCESS;
@@ -306,18 +310,18 @@ nssList_Clone(nssList *list)
nssListElement *node;
rvList = nssList_Create(NULL, (list->lock != NULL));
if (!rvList) {
- return NULL;
+ return NULL;
}
NSSLIST_LOCK_IF(list);
if (list->count > 0) {
- node = list->head;
- while (PR_TRUE) {
- nssList_Add(rvList, node->data);
- node = (nssListElement *)PR_NEXT_LINK(&node->link);
- if (node == list->head) {
- break;
- }
- }
+ node = list->head;
+ while (PR_TRUE) {
+ nssList_Add(rvList, node->data);
+ node = (nssListElement *)PR_NEXT_LINK(&node->link);
+ if (node == list->head) {
+ break;
+ }
+ }
}
NSSLIST_UNLOCK_IF(list);
return rvList;
@@ -329,21 +333,21 @@ nssList_CreateIterator(nssList *list)
nssListIterator *rvIterator;
rvIterator = nss_ZNEW(NULL, nssListIterator);
if (!rvIterator) {
- return NULL;
+ return NULL;
}
rvIterator->list = nssList_Clone(list);
if (!rvIterator->list) {
- nss_ZFreeIf(rvIterator);
- return NULL;
+ nss_ZFreeIf(rvIterator);
+ return NULL;
}
rvIterator->current = rvIterator->list->head;
if (list->lock) {
- rvIterator->lock = PZ_NewLock(nssILockOther);
- if (!rvIterator->lock) {
- nssList_Destroy(rvIterator->list);
- nss_ZFreeIf(rvIterator);
- rvIterator = NULL;
- }
+ rvIterator->lock = PZ_NewLock(nssILockOther);
+ if (!rvIterator->lock) {
+ nssList_Destroy(rvIterator->list);
+ nss_ZFreeIf(rvIterator);
+ rvIterator = NULL;
+ }
}
return rvIterator;
}
@@ -352,9 +356,11 @@ NSS_IMPLEMENT void
nssListIterator_Destroy(nssListIterator *iter)
{
if (iter->lock) {
- (void)PZ_DestroyLock(iter->lock);
+ (void)PZ_DestroyLock(iter->lock);
+ }
+ if (iter->list) {
+ nssList_Destroy(iter->list);
}
- nssList_Destroy(iter->list);
nss_ZFreeIf(iter);
}
@@ -363,7 +369,7 @@ nssListIterator_Start(nssListIterator *iter)
{
NSSLIST_LOCK_IF(iter);
if (iter->list->count == 0) {
- return NULL;
+ return NULL;
}
iter->current = iter->list->head;
return iter->current->data;
@@ -375,17 +381,17 @@ nssListIterator_Next(nssListIterator *iter)
nssListElement *node;
PRCList *link;
if (iter->list->count == 1 || iter->current == NULL) {
- /* Reached the end of the list. Don't change the state, force to
- * user to call nssList_Finish to clean up.
- */
- return NULL;
+ /* Reached the end of the list. Don't change the state, force to
+ * user to call nssList_Finish to clean up.
+ */
+ return NULL;
}
node = (nssListElement *)PR_NEXT_LINK(&iter->current->link);
link = &node->link;
if (link == PR_LIST_TAIL(&iter->list->head->link)) {
- /* Signal the end of the list. */
- iter->current = NULL;
- return node->data;
+ /* Signal the end of the list. */
+ iter->current = NULL;
+ return node->data;
}
iter->current = node;
return node->data;
@@ -397,4 +403,3 @@ nssListIterator_Finish(nssListIterator *iter)
iter->current = iter->list->head;
return (iter->lock) ? PZ_Unlock(iter->lock) : PR_SUCCESS;
}
-