1 /* ***** BEGIN LICENSE BLOCK *****
2 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 * The contents of this file are subject to the Mozilla Public License Version
5 * 1.1 (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 * http://www.mozilla.org/MPL/
9 * Software distributed under the License is distributed on an "AS IS" basis,
10 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11 * for the specific language governing rights and limitations under the
14 * The Original Code is the Netscape security libraries.
16 * The Initial Developer of the Original Code is
17 * Netscape Communications Corporation.
18 * Portions created by the Initial Developer are Copyright (C) 1994-2000
19 * the Initial Developer. All Rights Reserved.
23 * Alternatively, the contents of this file may be used under the terms of
24 * either the GNU General Public License Version 2 or later (the "GPL"), or
25 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
26 * in which case the provisions of the GPL or the LGPL are applicable instead
27 * of those above. If you wish to allow use of your version of this file only
28 * under the terms of either the GPL or the LGPL, and not to allow others to
29 * use your version of this file under the terms of the MPL, indicate your
30 * decision by deleting the provisions above and replace them with the notice
31 * and other provisions required by the GPL or the LGPL. If you do not delete
32 * the provisions above, a recipient may use your version of this file under
33 * the terms of any one of the MPL, the GPL or the LGPL.
35 * ***** END LICENSE BLOCK ***** */
38 static const char CVS_ID
[] = "@(#) $RCSfile: hash.c,v $ $Revision: 1.3 $ $Date: 2005/01/20 02:25:45 $";
44 * This is merely a couple wrappers around NSPR's PLHashTable, using
45 * the identity hash and arena-aware allocators. The reason I did
46 * this is that hash tables are used in a few places throughout the
47 * NSS Cryptoki Framework in a fairly stereotyped way, and this allows
48 * me to pull the commonalities into one place. Should we ever want
49 * to change the implementation, it's all right here.
69 struct nssCKFWHashStr
{
73 * The invariant that mutex protects is:
74 * The count accurately reflects the hashtable state.
77 PLHashTable
*plHashTable
;
82 nss_ckfw_identity_hash
87 PRUint32 i
= (PRUint32
)key
;
88 PR_ASSERT(sizeof(PLHashNumber
) == sizeof(PRUint32
));
89 return (PLHashNumber
)i
;
96 NSS_IMPLEMENT nssCKFWHash
*
99 NSSCKFWInstance
*fwInstance
,
107 if( (CK_RV
*)NULL
== pError
) {
108 return (nssCKFWHash
*)NULL
;
111 if( PR_SUCCESS
!= nssArena_verifyPointer(arena
) ) {
112 *pError
= CKR_ARGUMENTS_BAD
;
113 return (nssCKFWHash
*)NULL
;
115 #endif /* NSSDEBUG */
117 rv
= nss_ZNEW(arena
, nssCKFWHash
);
118 if( (nssCKFWHash
*)NULL
== rv
) {
119 *pError
= CKR_HOST_MEMORY
;
120 return (nssCKFWHash
*)NULL
;
123 rv
->mutex
= nssCKFWInstance_CreateMutex(fwInstance
, arena
, pError
);
124 if( (NSSCKFWMutex
*)NULL
== rv
->mutex
) {
125 if( CKR_OK
== *pError
) {
126 *pError
= CKR_GENERAL_ERROR
;
128 return (nssCKFWHash
*)NULL
;
131 rv
->plHashTable
= PL_NewHashTable(0, nss_ckfw_identity_hash
,
132 PL_CompareValues
, PL_CompareValues
, &nssArenaHashAllocOps
, arena
);
133 if( (PLHashTable
*)NULL
== rv
->plHashTable
) {
134 (void)nssCKFWMutex_Destroy(rv
->mutex
);
135 (void)nss_ZFreeIf(rv
);
136 *pError
= CKR_HOST_MEMORY
;
137 return (nssCKFWHash
*)NULL
;
146 * nssCKFWHash_Destroy
155 (void)nssCKFWMutex_Destroy(hash
->mutex
);
156 PL_HashTableDestroy(hash
->plHashTable
);
157 (void)nss_ZFreeIf(hash
);
172 CK_RV error
= CKR_OK
;
175 error
= nssCKFWMutex_Lock(hash
->mutex
);
176 if( CKR_OK
!= error
) {
180 he
= PL_HashTableAdd(hash
->plHashTable
, key
, (void *)value
);
181 if( (PLHashEntry
*)NULL
== he
) {
182 error
= CKR_HOST_MEMORY
;
187 (void)nssCKFWMutex_Unlock(hash
->mutex
);
205 if( CKR_OK
!= nssCKFWMutex_Lock(hash
->mutex
) ) {
209 found
= PL_HashTableRemove(hash
->plHashTable
, it
);
214 (void)nssCKFWMutex_Unlock(hash
->mutex
);
222 NSS_IMPLEMENT CK_ULONG
230 if( CKR_OK
!= nssCKFWMutex_Lock(hash
->mutex
) ) {
236 (void)nssCKFWMutex_Unlock(hash
->mutex
);
245 NSS_IMPLEMENT CK_BBOOL
254 if( CKR_OK
!= nssCKFWMutex_Lock(hash
->mutex
) ) {
258 value
= PL_HashTableLookup(hash
->plHashTable
, it
);
260 (void)nssCKFWMutex_Unlock(hash
->mutex
);
262 if( (void *)NULL
== value
) {
282 if( CKR_OK
!= nssCKFWMutex_Lock(hash
->mutex
) ) {
286 rv
= PL_HashTableLookup(hash
->plHashTable
, it
);
288 (void)nssCKFWMutex_Unlock(hash
->mutex
);
294 nssCKFWHashIterator fcn
;
299 nss_ckfwhash_enumerator
306 struct arg_str
*as
= (struct arg_str
*)arg
;
307 as
->fcn(he
->key
, he
->value
, as
->closure
);
308 return HT_ENUMERATE_NEXT
;
312 * nssCKFWHash_Iterate
314 * NOTE that the iteration function will be called with the hashtable locked.
320 nssCKFWHashIterator fcn
,
326 as
.closure
= closure
;
328 if( CKR_OK
!= nssCKFWMutex_Lock(hash
->mutex
) ) {
332 PL_HashTableEnumerateEntries(hash
->plHashTable
, nss_ckfwhash_enumerator
, &as
);
334 (void)nssCKFWMutex_Unlock(hash
->mutex
);