| OLD | NEW |
| 1 /* This Source Code Form is subject to the terms of the Mozilla Public | 1 /* This Source Code Form is subject to the terms of the Mozilla Public |
| 2 * License, v. 2.0. If a copy of the MPL was not distributed with this | 2 * License, v. 2.0. If a copy of the MPL was not distributed with this |
| 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
| 4 | 4 |
| 5 /* | 5 /* |
| 6 * hash.c | 6 * hash.c |
| 7 * | 7 * |
| 8 * This is merely a couple wrappers around NSPR's PLHashTable, using | 8 * This is merely a couple wrappers around NSPR's PLHashTable, using |
| 9 * the identity hash and arena-aware allocators. The reason I did | 9 * the identity hash and arena-aware allocators. The reason I did |
| 10 * this is that hash tables are used in a few places throughout the | 10 * this is that hash tables are used in a few places throughout the |
| (...skipping 13 matching lines...) Expand all Loading... |
| 24 * nssCKFWHash_Destroy | 24 * nssCKFWHash_Destroy |
| 25 * nssCKFWHash_Add | 25 * nssCKFWHash_Add |
| 26 * nssCKFWHash_Remove | 26 * nssCKFWHash_Remove |
| 27 * nssCKFWHash_Count | 27 * nssCKFWHash_Count |
| 28 * nssCKFWHash_Exists | 28 * nssCKFWHash_Exists |
| 29 * nssCKFWHash_Lookup | 29 * nssCKFWHash_Lookup |
| 30 * nssCKFWHash_Iterate | 30 * nssCKFWHash_Iterate |
| 31 */ | 31 */ |
| 32 | 32 |
| 33 struct nssCKFWHashStr { | 33 struct nssCKFWHashStr { |
| 34 NSSCKFWMutex *mutex; | 34 NSSCKFWMutex *mutex; |
| 35 | 35 |
| 36 /* | 36 /* |
| 37 * The invariant that mutex protects is: | 37 * The invariant that mutex protects is: |
| 38 * The count accurately reflects the hashtable state. | 38 * The count accurately reflects the hashtable state. |
| 39 */ | 39 */ |
| 40 | 40 |
| 41 PLHashTable *plHashTable; | 41 PLHashTable *plHashTable; |
| 42 CK_ULONG count; | 42 CK_ULONG count; |
| 43 }; | 43 }; |
| 44 | 44 |
| 45 static PLHashNumber | 45 static PLHashNumber |
| 46 nss_ckfw_identity_hash | 46 nss_ckfw_identity_hash( |
| 47 ( | 47 const void *key) |
| 48 const void *key | |
| 49 ) | |
| 50 { | 48 { |
| 51 return (PLHashNumber)((char *)key - (char *)NULL); | 49 return (PLHashNumber)((char *)key - (char *)NULL); |
| 52 } | 50 } |
| 53 | 51 |
| 54 /* | 52 /* |
| 55 * nssCKFWHash_Create | 53 * nssCKFWHash_Create |
| 56 * | 54 * |
| 57 */ | 55 */ |
| 58 NSS_IMPLEMENT nssCKFWHash * | 56 NSS_IMPLEMENT nssCKFWHash * |
| 59 nssCKFWHash_Create | 57 nssCKFWHash_Create( |
| 60 ( | 58 NSSCKFWInstance *fwInstance, |
| 61 NSSCKFWInstance *fwInstance, | 59 NSSArena *arena, |
| 62 NSSArena *arena, | 60 CK_RV *pError) |
| 63 CK_RV *pError | |
| 64 ) | |
| 65 { | 61 { |
| 66 nssCKFWHash *rv; | 62 nssCKFWHash *rv; |
| 67 | 63 |
| 68 #ifdef NSSDEBUG | 64 #ifdef NSSDEBUG |
| 69 if (!pError) { | 65 if (!pError) { |
| 70 return (nssCKFWHash *)NULL; | 66 return (nssCKFWHash *)NULL; |
| 71 } | 67 } |
| 72 | 68 |
| 73 if( PR_SUCCESS != nssArena_verifyPointer(arena) ) { | 69 if (PR_SUCCESS != nssArena_verifyPointer(arena)) { |
| 74 *pError = CKR_ARGUMENTS_BAD; | 70 *pError = CKR_ARGUMENTS_BAD; |
| 75 return (nssCKFWHash *)NULL; | 71 return (nssCKFWHash *)NULL; |
| 76 } | 72 } |
| 77 #endif /* NSSDEBUG */ | 73 #endif /* NSSDEBUG */ |
| 78 | 74 |
| 79 rv = nss_ZNEW(arena, nssCKFWHash); | 75 rv = nss_ZNEW(arena, nssCKFWHash); |
| 80 if (!rv) { | 76 if (!rv) { |
| 81 *pError = CKR_HOST_MEMORY; | 77 *pError = CKR_HOST_MEMORY; |
| 82 return (nssCKFWHash *)NULL; | 78 return (nssCKFWHash *)NULL; |
| 83 } | 79 } |
| 84 | 80 |
| 85 rv->mutex = nssCKFWInstance_CreateMutex(fwInstance, arena, pError); | 81 rv->mutex = nssCKFWInstance_CreateMutex(fwInstance, arena, pError); |
| 86 if (!rv->mutex) { | 82 if (!rv->mutex) { |
| 87 if( CKR_OK == *pError ) { | 83 if (CKR_OK == *pError) { |
| 88 *pError = CKR_GENERAL_ERROR; | 84 *pError = CKR_GENERAL_ERROR; |
| 85 } |
| 86 (void)nss_ZFreeIf(rv); |
| 87 return (nssCKFWHash *)NULL; |
| 89 } | 88 } |
| 90 (void)nss_ZFreeIf(rv); | |
| 91 return (nssCKFWHash *)NULL; | |
| 92 } | |
| 93 | 89 |
| 94 rv->plHashTable = PL_NewHashTable(0, nss_ckfw_identity_hash, | 90 rv->plHashTable = PL_NewHashTable(0, nss_ckfw_identity_hash, |
| 95 PL_CompareValues, PL_CompareValues, &nssArenaHashAllocOps, arena); | 91 PL_CompareValues, PL_CompareValues, &nssAr
enaHashAllocOps, arena); |
| 96 if (!rv->plHashTable) { | 92 if (!rv->plHashTable) { |
| 97 (void)nssCKFWMutex_Destroy(rv->mutex); | 93 (void)nssCKFWMutex_Destroy(rv->mutex); |
| 98 (void)nss_ZFreeIf(rv); | 94 (void)nss_ZFreeIf(rv); |
| 99 *pError = CKR_HOST_MEMORY; | 95 *pError = CKR_HOST_MEMORY; |
| 100 return (nssCKFWHash *)NULL; | 96 return (nssCKFWHash *)NULL; |
| 101 } | 97 } |
| 102 | 98 |
| 103 rv->count = 0; | 99 rv->count = 0; |
| 104 | 100 |
| 105 return rv; | 101 return rv; |
| 106 } | 102 } |
| 107 | 103 |
| 108 /* | 104 /* |
| 109 * nssCKFWHash_Destroy | 105 * nssCKFWHash_Destroy |
| 110 * | 106 * |
| 111 */ | 107 */ |
| 112 NSS_IMPLEMENT void | 108 NSS_IMPLEMENT void |
| 113 nssCKFWHash_Destroy | 109 nssCKFWHash_Destroy( |
| 114 ( | 110 nssCKFWHash *hash) |
| 115 nssCKFWHash *hash | |
| 116 ) | |
| 117 { | 111 { |
| 118 (void)nssCKFWMutex_Destroy(hash->mutex); | 112 (void)nssCKFWMutex_Destroy(hash->mutex); |
| 119 PL_HashTableDestroy(hash->plHashTable); | 113 PL_HashTableDestroy(hash->plHashTable); |
| 120 (void)nss_ZFreeIf(hash); | 114 (void)nss_ZFreeIf(hash); |
| 121 } | 115 } |
| 122 | 116 |
| 123 /* | 117 /* |
| 124 * nssCKFWHash_Add | 118 * nssCKFWHash_Add |
| 125 * | 119 * |
| 126 */ | 120 */ |
| 127 NSS_IMPLEMENT CK_RV | 121 NSS_IMPLEMENT CK_RV |
| 128 nssCKFWHash_Add | 122 nssCKFWHash_Add( |
| 129 ( | 123 nssCKFWHash *hash, |
| 130 nssCKFWHash *hash, | 124 const void *key, |
| 131 const void *key, | 125 const void *value) |
| 132 const void *value | |
| 133 ) | |
| 134 { | 126 { |
| 135 CK_RV error = CKR_OK; | 127 CK_RV error = CKR_OK; |
| 136 PLHashEntry *he; | 128 PLHashEntry *he; |
| 137 | 129 |
| 138 error = nssCKFWMutex_Lock(hash->mutex); | 130 error = nssCKFWMutex_Lock(hash->mutex); |
| 139 if( CKR_OK != error ) { | 131 if (CKR_OK != error) { |
| 132 return error; |
| 133 } |
| 134 |
| 135 he = PL_HashTableAdd(hash->plHashTable, key, (void *)value); |
| 136 if (!he) { |
| 137 error = CKR_HOST_MEMORY; |
| 138 } else { |
| 139 hash->count++; |
| 140 } |
| 141 |
| 142 (void)nssCKFWMutex_Unlock(hash->mutex); |
| 143 |
| 140 return error; | 144 return error; |
| 141 } | |
| 142 | |
| 143 he = PL_HashTableAdd(hash->plHashTable, key, (void *)value); | |
| 144 if (!he) { | |
| 145 error = CKR_HOST_MEMORY; | |
| 146 } else { | |
| 147 hash->count++; | |
| 148 } | |
| 149 | |
| 150 (void)nssCKFWMutex_Unlock(hash->mutex); | |
| 151 | |
| 152 return error; | |
| 153 } | 145 } |
| 154 | 146 |
| 155 /* | 147 /* |
| 156 * nssCKFWHash_Remove | 148 * nssCKFWHash_Remove |
| 157 * | 149 * |
| 158 */ | 150 */ |
| 159 NSS_IMPLEMENT void | 151 NSS_IMPLEMENT void |
| 160 nssCKFWHash_Remove | 152 nssCKFWHash_Remove( |
| 161 ( | 153 nssCKFWHash *hash, |
| 162 nssCKFWHash *hash, | 154 const void *it) |
| 163 const void *it | |
| 164 ) | |
| 165 { | 155 { |
| 166 PRBool found; | 156 PRBool found; |
| 167 | 157 |
| 168 if( CKR_OK != nssCKFWMutex_Lock(hash->mutex) ) { | 158 if (CKR_OK != nssCKFWMutex_Lock(hash->mutex)) { |
| 159 return; |
| 160 } |
| 161 |
| 162 found = PL_HashTableRemove(hash->plHashTable, it); |
| 163 if (found) { |
| 164 hash->count--; |
| 165 } |
| 166 |
| 167 (void)nssCKFWMutex_Unlock(hash->mutex); |
| 169 return; | 168 return; |
| 170 } | |
| 171 | |
| 172 found = PL_HashTableRemove(hash->plHashTable, it); | |
| 173 if( found ) { | |
| 174 hash->count--; | |
| 175 } | |
| 176 | |
| 177 (void)nssCKFWMutex_Unlock(hash->mutex); | |
| 178 return; | |
| 179 } | 169 } |
| 180 | 170 |
| 181 /* | 171 /* |
| 182 * nssCKFWHash_Count | 172 * nssCKFWHash_Count |
| 183 * | 173 * |
| 184 */ | 174 */ |
| 185 NSS_IMPLEMENT CK_ULONG | 175 NSS_IMPLEMENT CK_ULONG |
| 186 nssCKFWHash_Count | 176 nssCKFWHash_Count( |
| 187 ( | 177 nssCKFWHash *hash) |
| 188 nssCKFWHash *hash | |
| 189 ) | |
| 190 { | 178 { |
| 191 CK_ULONG count; | 179 CK_ULONG count; |
| 192 | 180 |
| 193 if( CKR_OK != nssCKFWMutex_Lock(hash->mutex) ) { | 181 if (CKR_OK != nssCKFWMutex_Lock(hash->mutex)) { |
| 194 return (CK_ULONG)0; | 182 return (CK_ULONG)0; |
| 195 } | 183 } |
| 196 | 184 |
| 197 count = hash->count; | 185 count = hash->count; |
| 198 | 186 |
| 199 (void)nssCKFWMutex_Unlock(hash->mutex); | 187 (void)nssCKFWMutex_Unlock(hash->mutex); |
| 200 | 188 |
| 201 return count; | 189 return count; |
| 202 } | 190 } |
| 203 | 191 |
| 204 /* | 192 /* |
| 205 * nssCKFWHash_Exists | 193 * nssCKFWHash_Exists |
| 206 * | 194 * |
| 207 */ | 195 */ |
| 208 NSS_IMPLEMENT CK_BBOOL | 196 NSS_IMPLEMENT CK_BBOOL |
| 209 nssCKFWHash_Exists | 197 nssCKFWHash_Exists( |
| 210 ( | 198 nssCKFWHash *hash, |
| 211 nssCKFWHash *hash, | 199 const void *it) |
| 212 const void *it | |
| 213 ) | |
| 214 { | 200 { |
| 215 void *value; | 201 void *value; |
| 216 | 202 |
| 217 if( CKR_OK != nssCKFWMutex_Lock(hash->mutex) ) { | 203 if (CKR_OK != nssCKFWMutex_Lock(hash->mutex)) { |
| 218 return CK_FALSE; | 204 return CK_FALSE; |
| 219 } | 205 } |
| 220 | 206 |
| 221 value = PL_HashTableLookup(hash->plHashTable, it); | 207 value = PL_HashTableLookup(hash->plHashTable, it); |
| 222 | 208 |
| 223 (void)nssCKFWMutex_Unlock(hash->mutex); | 209 (void)nssCKFWMutex_Unlock(hash->mutex); |
| 224 | 210 |
| 225 if (!value) { | 211 if (!value) { |
| 226 return CK_FALSE; | 212 return CK_FALSE; |
| 227 } else { | 213 } else { |
| 228 return CK_TRUE; | 214 return CK_TRUE; |
| 229 } | 215 } |
| 230 } | 216 } |
| 231 | 217 |
| 232 /* | 218 /* |
| 233 * nssCKFWHash_Lookup | 219 * nssCKFWHash_Lookup |
| 234 * | 220 * |
| 235 */ | 221 */ |
| 236 NSS_IMPLEMENT void * | 222 NSS_IMPLEMENT void * |
| 237 nssCKFWHash_Lookup | 223 nssCKFWHash_Lookup( |
| 238 ( | 224 nssCKFWHash *hash, |
| 239 nssCKFWHash *hash, | 225 const void *it) |
| 240 const void *it | |
| 241 ) | |
| 242 { | 226 { |
| 243 void *rv; | 227 void *rv; |
| 244 | 228 |
| 245 if( CKR_OK != nssCKFWMutex_Lock(hash->mutex) ) { | 229 if (CKR_OK != nssCKFWMutex_Lock(hash->mutex)) { |
| 246 return (void *)NULL; | 230 return (void *)NULL; |
| 247 } | 231 } |
| 248 | 232 |
| 249 rv = PL_HashTableLookup(hash->plHashTable, it); | 233 rv = PL_HashTableLookup(hash->plHashTable, it); |
| 250 | 234 |
| 251 (void)nssCKFWMutex_Unlock(hash->mutex); | 235 (void)nssCKFWMutex_Unlock(hash->mutex); |
| 252 | 236 |
| 253 return rv; | 237 return rv; |
| 254 } | 238 } |
| 255 | 239 |
| 256 struct arg_str { | 240 struct arg_str { |
| 257 nssCKFWHashIterator fcn; | 241 nssCKFWHashIterator fcn; |
| 258 void *closure; | 242 void *closure; |
| 259 }; | 243 }; |
| 260 | 244 |
| 261 static PRIntn | 245 static PRIntn |
| 262 nss_ckfwhash_enumerator | 246 nss_ckfwhash_enumerator( |
| 263 ( | 247 PLHashEntry *he, |
| 264 PLHashEntry *he, | 248 PRIntn index, |
| 265 PRIntn index, | 249 void *arg) |
| 266 void *arg | |
| 267 ) | |
| 268 { | 250 { |
| 269 struct arg_str *as = (struct arg_str *)arg; | 251 struct arg_str *as = (struct arg_str *)arg; |
| 270 as->fcn(he->key, he->value, as->closure); | 252 as->fcn(he->key, he->value, as->closure); |
| 271 return HT_ENUMERATE_NEXT; | 253 return HT_ENUMERATE_NEXT; |
| 272 } | 254 } |
| 273 | 255 |
| 274 /* | 256 /* |
| 275 * nssCKFWHash_Iterate | 257 * nssCKFWHash_Iterate |
| 276 * | 258 * |
| 277 * NOTE that the iteration function will be called with the hashtable locked. | 259 * NOTE that the iteration function will be called with the hashtable locked. |
| 278 */ | 260 */ |
| 279 NSS_IMPLEMENT void | 261 NSS_IMPLEMENT void |
| 280 nssCKFWHash_Iterate | 262 nssCKFWHash_Iterate( |
| 281 ( | 263 nssCKFWHash *hash, |
| 282 nssCKFWHash *hash, | 264 nssCKFWHashIterator fcn, |
| 283 nssCKFWHashIterator fcn, | 265 void *closure) |
| 284 void *closure | |
| 285 ) | |
| 286 { | 266 { |
| 287 struct arg_str as; | 267 struct arg_str as; |
| 288 as.fcn = fcn; | 268 as.fcn = fcn; |
| 289 as.closure = closure; | 269 as.closure = closure; |
| 290 | 270 |
| 291 if( CKR_OK != nssCKFWMutex_Lock(hash->mutex) ) { | 271 if (CKR_OK != nssCKFWMutex_Lock(hash->mutex)) { |
| 272 return; |
| 273 } |
| 274 |
| 275 PL_HashTableEnumerateEntries(hash->plHashTable, nss_ckfwhash_enumerator, &as
); |
| 276 |
| 277 (void)nssCKFWMutex_Unlock(hash->mutex); |
| 278 |
| 292 return; | 279 return; |
| 293 } | |
| 294 | |
| 295 PL_HashTableEnumerateEntries(hash->plHashTable, nss_ckfwhash_enumerator, &as); | |
| 296 | |
| 297 (void)nssCKFWMutex_Unlock(hash->mutex); | |
| 298 | |
| 299 return; | |
| 300 } | 280 } |
| OLD | NEW |