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 |