From dbf91db041f5892012f4f3124ef0886f99d7b96e Mon Sep 17 00:00:00 2001 From: "ian.mcgreer%sun.com" Date: Mon, 8 Oct 2001 19:26:02 +0000 Subject: [PATCH] implement hash keyed by NSSItem; change list method names to be like hash method names; fix 99214, arena mark lists broken --- security/nss/lib/base/arena.c | 64 ++++++++++++++++--------- security/nss/lib/base/base.h | 35 ++++++++++---- security/nss/lib/base/hash.c | 89 ++++++++++++++++++++++++++++++++--- security/nss/lib/base/list.c | 15 +++--- 4 files changed, 156 insertions(+), 47 deletions(-) diff --git a/security/nss/lib/base/arena.c b/security/nss/lib/base/arena.c index 35a68c5263e..ee3573ce28e 100644 --- a/security/nss/lib/base/arena.c +++ b/security/nss/lib/base/arena.c @@ -32,7 +32,7 @@ */ #ifdef DEBUG -static const char CVS_ID[] = "@(#) $RCSfile: arena.c,v $ $Revision: 1.2 $ $Date: 2000-04-19 21:23:13 $ $Name: $"; +static const char CVS_ID[] = "@(#) $RCSfile: arena.c,v $ $Revision: 1.3 $ $Date: 2001-10-08 19:26:01 $ $Name: $"; #endif /* DEBUG */ /* @@ -542,6 +542,8 @@ nssArena_Destroy return PR_SUCCESS; } +static void *nss_zalloc_arena_locked(NSSArena *arena, PRUint32 size); + /* * nssArena_Mark * @@ -604,7 +606,7 @@ nssArena_Mark /* No error possible */ /* Do this after the mark */ - rv = nss_ZNEW(arena, nssArenaMark); + rv = (nssArenaMark *)nss_zalloc_arena_locked(arena, sizeof(nssArenaMark)); if( (nssArenaMark *)NULL == rv ) { PR_Unlock(arena->lock); nss_SetError(NSS_ERROR_NO_MEMORY); @@ -612,8 +614,13 @@ nssArena_Mark } #ifdef ARENA_THREADMARK - arena->last_mark->next = rv; - arena->last_mark = rv; + if ( (nssArenaMark *)NULL == arena->first_mark) { + arena->first_mark = rv; + arena->last_mark = rv; + } else { + arena->last_mark->next = rv; + arena->last_mark = rv; + } #endif /* ARENA_THREADMARK */ rv->mark = p; @@ -806,6 +813,35 @@ struct pointer_header { PRUint32 size; }; +static void * +nss_zalloc_arena_locked +( + NSSArena *arena, + PRUint32 size +) +{ + void *p; + void *rv; + struct pointer_header *h; + PRUint32 my_size = size + sizeof(struct pointer_header); + PR_ARENA_ALLOCATE(p, &arena->pool, my_size); + if( (void *)NULL == p ) { + nss_SetError(NSS_ERROR_NO_MEMORY); + return (void *)NULL; + } + /* + * Do this before we unlock. This way if the user is using + * an arena in one thread while destroying it in another, he'll + * fault/FMR in his code, not ours. + */ + h = (struct pointer_header *)p; + h->arena = arena; + h->size = size; + rv = (void *)((char *)h + sizeof(struct pointer_header)); + (void)nsslibc_memset(rv, 0, size); + return rv; +} + /* * nss_ZAlloc * @@ -859,7 +895,6 @@ nss_ZAlloc return (void *)((char *)h + sizeof(struct pointer_header)); } else { - void *p; void *rv; /* Arena allocation */ #ifdef NSSDEBUG @@ -885,26 +920,9 @@ nss_ZAlloc } #endif /* ARENA_THREADMARK */ - PR_ARENA_ALLOCATE(p, &arenaOpt->pool, my_size); - if( (void *)NULL == p ) { - PR_Unlock(arenaOpt->lock); - nss_SetError(NSS_ERROR_NO_MEMORY); - return (void *)NULL; - } - - /* - * Do this before we unlock. This way if the user is using - * an arena in one thread while destroying it in another, he'll - * fault/FMR in his code, not ours. - */ - h = (struct pointer_header *)p; - h->arena = arenaOpt; - h->size = size; - rv = (void *)((char *)h + sizeof(struct pointer_header)); - (void)nsslibc_memset(rv, 0, size); + rv = nss_zalloc_arena_locked(arenaOpt, size); PR_Unlock(arenaOpt->lock); - return rv; } /*NOTREACHED*/ diff --git a/security/nss/lib/base/base.h b/security/nss/lib/base/base.h index f563e1f61d6..c11734375dc 100644 --- a/security/nss/lib/base/base.h +++ b/security/nss/lib/base/base.h @@ -35,7 +35,7 @@ #define BASE_H #ifdef DEBUG -static const char BASE_CVS_ID[] = "@(#) $RCSfile: base.h,v $ $Revision: 1.7 $ $Date: 2001-09-25 20:48:51 $ $Name: $"; +static const char BASE_CVS_ID[] = "@(#) $RCSfile: base.h,v $ $Revision: 1.8 $ $Date: 2001-10-08 19:26:02 $ $Name: $"; #endif /* DEBUG */ /* @@ -853,44 +853,44 @@ nssList_SetCompareFunction ); /* - * nssList_AddElement + * nssList_Add */ NSS_EXTERN PRStatus -nssList_AddElement +nssList_Add ( nssList *list, void *data ); /* - * nssList_AddElementUnique + * nssList_AddUnique * * This will use the compare function to see if the element is already * in the list. */ NSS_EXTERN PRStatus -nssList_AddElementUnique +nssList_AddUnique ( nssList *list, void *data ); /* - * nssList_RemoveElement + * nssList_Remove * * Uses the compare function to locate the element and remove it. */ NSS_EXTERN PRStatus -nssList_RemoveElement(nssList *list, void *data); +nssList_Remove(nssList *list, void *data); /* - * nssList_GetElement + * nssList_Get * * Uses the compare function to locate an element. Also serves as * nssList_Exists. */ NSS_EXTERN void * -nssList_GetElement +nssList_Get ( nssList *list, void *data @@ -991,8 +991,23 @@ nssListIterator_Finish * nssHash_Create * */ + NSS_EXTERN nssHash * -nssHash_Create +nssHash_CreatePointer +( + NSSArena *arenaOpt, + PRUint32 numBuckets +); + +NSS_EXTERN nssHash * +nssHash_CreateString +( + NSSArena *arenaOpt, + PRUint32 numBuckets +); + +NSS_EXTERN nssHash * +nssHash_CreateItem ( NSSArena *arenaOpt, PRUint32 numBuckets diff --git a/security/nss/lib/base/hash.c b/security/nss/lib/base/hash.c index 3342338af4c..2c70bfca9a4 100644 --- a/security/nss/lib/base/hash.c +++ b/security/nss/lib/base/hash.c @@ -32,7 +32,7 @@ */ #ifdef DEBUG -static const char CVS_ID[] = "@(#) $RCSfile: hash.c,v $ $Revision: 1.2 $ $Date: 2001-10-03 14:07:29 $ $Name: $"; +static const char CVS_ID[] = "@(#) $RCSfile: hash.c,v $ $Revision: 1.3 $ $Date: 2001-10-08 19:26:02 $ $Name: $"; #endif /* DEBUG */ /* @@ -86,15 +86,40 @@ nss_identity_hash return (PLHashNumber)i; } +static PLHashNumber +nss_item_hash +( + const void *key +) +{ + int i; + PLHashNumber h; + NSSItem *it = (NSSItem *)key; + h = 0; + for (i=0; isize; i++) + h = (h >> 28) ^ (h << 4) ^ ((unsigned char *)it->data)[i]; + return h; +} + +static int +nss_compare_items(const void *v1, const void *v2) +{ + PRStatus ignore; + return (int)nssItem_Equal((NSSItem *)v1, (NSSItem *)v2, &ignore); +} + /* - * nssHash_Create + * nssHash_create * */ -NSS_IMPLEMENT nssHash * +static nssHash * nssHash_Create ( NSSArena *arenaOpt, - PRUint32 numBuckets + PRUint32 numBuckets, + PLHashFunction keyHash, + PLHashComparator keyCompare, + PLHashComparator valueCompare ) { nssHash *rv; @@ -123,8 +148,9 @@ nssHash_Create goto loser; } - rv->plHashTable = PL_NewHashTable(numBuckets, nss_identity_hash, - PL_CompareValues, PL_CompareValues, &nssArenaHashAllocOps, arena); + rv->plHashTable = PL_NewHashTable(numBuckets, + keyHash, keyCompare, valueCompare, + &nssArenaHashAllocOps, arena); if( (PLHashTable *)NULL == rv->plHashTable ) { (void)PZ_DestroyLock(rv->mutex); goto loser; @@ -141,6 +167,51 @@ loser: return (nssHash *)NULL; } +/* + * nssHash_CreatePointer + * + */ +NSS_IMPLEMENT nssHash * +nssHash_CreatePointer +( + NSSArena *arenaOpt, + PRUint32 numBuckets +) +{ + return nssHash_Create(arenaOpt, numBuckets, + nss_identity_hash, PL_CompareValues, PL_CompareValues); +} + +/* + * nssHash_CreateString + * + */ +NSS_IMPLEMENT nssHash * +nssHash_CreateString +( + NSSArena *arenaOpt, + PRUint32 numBuckets +) +{ + return nssHash_Create(arenaOpt, numBuckets, + PL_HashString, PL_CompareStrings, PL_CompareStrings); +} + +/* + * nssHash_CreateItem + * + */ +NSS_IMPLEMENT nssHash * +nssHash_CreateItem +( + NSSArena *arenaOpt, + PRUint32 numBuckets +) +{ + return nssHash_Create(arenaOpt, numBuckets, + nss_item_hash, nss_compare_items, PL_CompareValues); +} + /* * nssHash_Destroy * @@ -153,7 +224,11 @@ nssHash_Destroy { (void)PZ_DestroyLock(hash->mutex); PL_HashTableDestroy(hash->plHashTable); - nssArena_Destroy(hash->arena); + if (hash->arena) { + nssArena_Destroy(hash->arena); + } else { + nss_ZFreeIf(hash); + } } /* diff --git a/security/nss/lib/base/list.c b/security/nss/lib/base/list.c index 0c66e8cfcd3..2889ed899cc 100644 --- a/security/nss/lib/base/list.c +++ b/security/nss/lib/base/list.c @@ -32,7 +32,7 @@ */ #ifdef DEBUG -static const char CVS_ID[] = "@(#) $RCSfile: list.c,v $ $Revision: 1.2 $ $Date: 2001-09-20 20:33:27 $ $Name: $"; +static const char CVS_ID[] = "@(#) $RCSfile: list.c,v $ $Revision: 1.3 $ $Date: 2001-10-08 19:26:02 $ $Name: $"; #endif /* DEBUG */ /* @@ -185,7 +185,7 @@ nsslist_add_element(nssList *list, void *data) } NSS_IMPLEMENT PRStatus -nssList_AddElement(nssList *list, void *data) +nssList_Add(nssList *list, void *data) { PRStatus nssrv; NSSLIST_LOCK_IF(list); @@ -195,7 +195,7 @@ nssList_AddElement(nssList *list, void *data) } NSS_IMPLEMENT PRStatus -nssList_AddElementUnique(nssList *list, void *data) +nssList_AddUnique(nssList *list, void *data) { PRStatus nssrv; nssListElement *node; @@ -212,7 +212,7 @@ nssList_AddElementUnique(nssList *list, void *data) } NSS_IMPLEMENT PRStatus -nssList_RemoveElement(nssList *list, void *data) +nssList_Remove(nssList *list, void *data) { nssListElement *node; NSSLIST_LOCK_IF(list); @@ -230,7 +230,7 @@ nssList_RemoveElement(nssList *list, void *data) } NSS_IMPLEMENT void * -nssList_GetElement(nssList *list, void *data) +nssList_Get(nssList *list, void *data) { nssListElement *node; NSSLIST_LOCK_IF(list); @@ -250,12 +250,13 @@ nssList_GetArray(nssList *list, void **rvArray, PRUint32 maxElements) { nssListIterator *iter; void *el; - int i = 0; + PRUint32 i = 0; iter = nssList_CreateIterator(list); - for (el = nssListIterator_Start(iter); el != NULL && i < maxElements; + for (el = nssListIterator_Start(iter); el != NULL; el = nssListIterator_Next(iter)) { rvArray[i++] = el; + if (maxElements > 0 && i == maxElements) break; } rvArray[i] = NULL; nssListIterator_Finish(iter);