Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(129)

Side by Side Diff: nss/lib/base/list.c

Issue 1843333003: Update NSPR to 4.12 and NSS to 3.23 on iOS (Closed) Base URL: https://chromium.googlesource.com/chromium/deps/nss.git@master
Patch Set: Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 * list.c 6 * list.c
7 * 7 *
8 * This contains the implementation of NSS's thread-safe linked list. 8 * This contains the implementation of NSS's thread-safe linked list.
9 */ 9 */
10 10
11 #ifndef BASE_H 11 #ifndef BASE_H
12 #include "base.h" 12 #include "base.h"
13 #endif /* BASE_H */ 13 #endif /* BASE_H */
14 14
15 struct nssListElementStr { 15 struct nssListElementStr {
16 PRCList link; 16 PRCList link;
17 void *data; 17 void *data;
18 }; 18 };
19 19
20 typedef struct nssListElementStr nssListElement; 20 typedef struct nssListElementStr nssListElement;
21 21
22 struct nssListStr { 22 struct nssListStr {
23 NSSArena *arena; 23 NSSArena *arena;
24 PZLock *lock; 24 PZLock *lock;
25 nssListElement *head; 25 nssListElement *head;
26 PRUint32 count; 26 PRUint32 count;
27 nssListCompareFunc compareFunc; 27 nssListCompareFunc compareFunc;
28 nssListSortFunc sortFunc; 28 nssListSortFunc sortFunc;
29 PRBool i_alloced_arena; 29 PRBool i_alloced_arena;
30 }; 30 };
31 31
32 struct nssListIteratorStr { 32 struct nssListIteratorStr {
33 PZLock *lock; 33 PZLock *lock;
34 nssList *list; 34 nssList *list;
35 nssListElement *current; 35 nssListElement *current;
36 }; 36 };
37 37
38 #define NSSLIST_LOCK_IF(list) \ 38 #define NSSLIST_LOCK_IF(list) \
39 if ((list)->lock) PZ_Lock((list)->lock) 39 if ((list)->lock) \
40 PZ_Lock((list)->lock)
40 41
41 #define NSSLIST_UNLOCK_IF(list) \ 42 #define NSSLIST_UNLOCK_IF(list) \
42 if ((list)->lock) PZ_Unlock((list)->lock) 43 if ((list)->lock) \
44 PZ_Unlock((list)->lock)
43 45
44 static PRBool 46 static PRBool
45 pointer_compare(void *a, void *b) 47 pointer_compare(void *a, void *b)
46 { 48 {
47 return (PRBool)(a == b); 49 return (PRBool)(a == b);
48 } 50 }
49 51
50 static nssListElement * 52 static nssListElement *
51 nsslist_get_matching_element(nssList *list, void *data) 53 nsslist_get_matching_element(nssList *list, void *data)
52 { 54 {
53 PRCList *link; 55 PRCList *link;
54 nssListElement *node; 56 nssListElement *node;
55 node = list->head; 57 node = list->head;
56 if (!node) { 58 if (!node) {
57 » return NULL; 59 return NULL;
58 } 60 }
59 link = &node->link; 61 link = &node->link;
60 while (node) { 62 while (node) {
61 » /* using a callback slows things down when it's just compare ... */ 63 /* using a callback slows things down when it's just compare ... */
62 » if (list->compareFunc(node->data, data)) { 64 if (list->compareFunc(node->data, data)) {
63 » break; 65 break;
64 » } 66 }
65 » link = &node->link; 67 link = &node->link;
66 » if (link == PR_LIST_TAIL(&list->head->link)) { 68 if (link == PR_LIST_TAIL(&list->head->link)) {
67 » node = NULL; 69 node = NULL;
68 » break; 70 break;
69 » } 71 }
70 » node = (nssListElement *)PR_NEXT_LINK(&node->link); 72 node = (nssListElement *)PR_NEXT_LINK(&node->link);
71 } 73 }
72 return node; 74 return node;
73 } 75 }
74 76
75 NSS_IMPLEMENT nssList * 77 NSS_IMPLEMENT nssList *
76 nssList_Create 78 nssList_Create(NSSArena *arenaOpt, PRBool threadSafe)
77 (
78 NSSArena *arenaOpt,
79 PRBool threadSafe
80 )
81 { 79 {
82 NSSArena *arena; 80 NSSArena *arena;
83 nssList *list; 81 nssList *list;
84 PRBool i_alloced; 82 PRBool i_alloced;
85 if (arenaOpt) { 83 if (arenaOpt) {
86 » arena = arenaOpt; 84 arena = arenaOpt;
87 » i_alloced = PR_FALSE; 85 i_alloced = PR_FALSE;
88 } else { 86 } else {
89 » arena = nssArena_Create(); 87 arena = nssArena_Create();
90 » i_alloced = PR_TRUE; 88 i_alloced = PR_TRUE;
91 } 89 }
92 if (!arena) { 90 if (!arena) {
93 » return (nssList *)NULL; 91 return (nssList *)NULL;
94 } 92 }
95 list = nss_ZNEW(arena, nssList); 93 list = nss_ZNEW(arena, nssList);
96 if (!list) { 94 if (!list) {
97 » if (!arenaOpt) { 95 if (!arenaOpt) {
98 » NSSArena_Destroy(arena); 96 NSSArena_Destroy(arena);
99 » } 97 }
100 » return (nssList *)NULL; 98 return (nssList *)NULL;
101 } 99 }
102 if (threadSafe) { 100 if (threadSafe) {
103 » list->lock = PZ_NewLock(nssILockOther); 101 list->lock = PZ_NewLock(nssILockOther);
104 » if (!list->lock) { 102 if (!list->lock) {
105 » if (arenaOpt) { 103 if (arenaOpt) {
106 » » nss_ZFreeIf(list); 104 nss_ZFreeIf(list);
107 » } else { 105 } else {
108 » » NSSArena_Destroy(arena); 106 NSSArena_Destroy(arena);
109 » } 107 }
110 » return (nssList *)NULL; 108 return (nssList *)NULL;
111 » } 109 }
112 } 110 }
113 list->arena = arena; 111 list->arena = arena;
114 list->i_alloced_arena = i_alloced; 112 list->i_alloced_arena = i_alloced;
115 list->compareFunc = pointer_compare; 113 list->compareFunc = pointer_compare;
116 return list; 114 return list;
117 } 115 }
118 116
119 NSS_IMPLEMENT PRStatus 117 NSS_IMPLEMENT PRStatus
120 nssList_Destroy(nssList *list) 118 nssList_Destroy(nssList *list)
121 { 119 {
122 if (!list->i_alloced_arena) { 120 if (!list->i_alloced_arena) {
123 » nssList_Clear(list, NULL); 121 nssList_Clear(list, NULL);
124 } 122 }
125 if (list->lock) { 123 if (list->lock) {
126 » (void)PZ_DestroyLock(list->lock); 124 (void)PZ_DestroyLock(list->lock);
127 } 125 }
128 if (list->i_alloced_arena) { 126 if (list->i_alloced_arena) {
129 » NSSArena_Destroy(list->arena); 127 NSSArena_Destroy(list->arena);
130 » list = NULL; 128 list = NULL;
131 } 129 }
132 nss_ZFreeIf(list); 130 nss_ZFreeIf(list);
133 return PR_SUCCESS; 131 return PR_SUCCESS;
134 } 132 }
135 133
136 NSS_IMPLEMENT void 134 NSS_IMPLEMENT void
137 nssList_SetCompareFunction(nssList *list, nssListCompareFunc compareFunc) 135 nssList_SetCompareFunction(nssList *list, nssListCompareFunc compareFunc)
138 { 136 {
139 list->compareFunc = compareFunc; 137 list->compareFunc = compareFunc;
140 } 138 }
(...skipping 13 matching lines...) Expand all
154 152
155 NSS_IMPLEMENT void 153 NSS_IMPLEMENT void
156 nssList_Clear(nssList *list, nssListElementDestructorFunc destructor) 154 nssList_Clear(nssList *list, nssListElementDestructorFunc destructor)
157 { 155 {
158 PRCList *link; 156 PRCList *link;
159 nssListElement *node, *tmp; 157 nssListElement *node, *tmp;
160 NSSLIST_LOCK_IF(list); 158 NSSLIST_LOCK_IF(list);
161 node = list->head; 159 node = list->head;
162 list->head = NULL; 160 list->head = NULL;
163 while (node && list->count > 0) { 161 while (node && list->count > 0) {
164 » if (destructor) (*destructor)(node->data); 162 if (destructor)
165 » link = &node->link; 163 (*destructor)(node->data);
166 » tmp = (nssListElement *)PR_NEXT_LINK(link); 164 link = &node->link;
167 » PR_REMOVE_LINK(link); 165 tmp = (nssListElement *)PR_NEXT_LINK(link);
168 » nss_ZFreeIf(node); 166 PR_REMOVE_LINK(link);
169 » node = tmp; 167 nss_ZFreeIf(node);
170 » --list->count; 168 node = tmp;
169 --list->count;
171 } 170 }
172 NSSLIST_UNLOCK_IF(list); 171 NSSLIST_UNLOCK_IF(list);
173 } 172 }
174 173
175 static PRStatus 174 static PRStatus
176 nsslist_add_element(nssList *list, void *data) 175 nsslist_add_element(nssList *list, void *data)
177 { 176 {
178 nssListElement *node = nss_ZNEW(list->arena, nssListElement); 177 nssListElement *node = nss_ZNEW(list->arena, nssListElement);
179 if (!node) { 178 if (!node) {
180 » return PR_FAILURE; 179 return PR_FAILURE;
181 } 180 }
182 PR_INIT_CLIST(&node->link); 181 PR_INIT_CLIST(&node->link);
183 node->data = data; 182 node->data = data;
184 if (list->head) { 183 if (list->head) {
185 » if (list->sortFunc) { 184 if (list->sortFunc) {
186 » PRCList *link; 185 PRCList *link;
187 » nssListElement *currNode; 186 nssListElement *currNode;
188 » currNode = list->head; 187 currNode = list->head;
189 » /* insert in ordered list */ 188 /* insert in ordered list */
190 » while (currNode) { 189 while (currNode) {
191 » » link = &currNode->link; 190 link = &currNode->link;
192 » » if (list->sortFunc(data, currNode->data) <= 0) { 191 if (list->sortFunc(data, currNode->data) <= 0) {
193 » » /* new element goes before current node */ 192 /* new element goes before current node */
194 » » PR_INSERT_BEFORE(&node->link, link); 193 PR_INSERT_BEFORE(&node->link, link);
195 » » /* reset head if this is first */ 194 /* reset head if this is first */
196 » » if (currNode == list->head) list->head = node; 195 if (currNode == list->head)
197 » » break; 196 list->head = node;
198 » » } 197 break;
199 » » if (link == PR_LIST_TAIL(&list->head->link)) { 198 }
200 » » /* reached end of list, append */ 199 if (link == PR_LIST_TAIL(&list->head->link)) {
201 » » PR_INSERT_AFTER(&node->link, link); 200 /* reached end of list, append */
202 » » break; 201 PR_INSERT_AFTER(&node->link, link);
203 » » } 202 break;
204 » » currNode = (nssListElement *)PR_NEXT_LINK(&currNode->link); 203 }
205 » } 204 currNode = (nssListElement *)PR_NEXT_LINK(&currNode->link);
206 » } else { 205 }
207 » /* not sorting */ 206 } else {
208 » PR_APPEND_LINK(&node->link, &list->head->link); 207 /* not sorting */
209 » } 208 PR_APPEND_LINK(&node->link, &list->head->link);
209 }
210 } else { 210 } else {
211 » list->head = node; 211 list->head = node;
212 } 212 }
213 ++list->count; 213 ++list->count;
214 return PR_SUCCESS; 214 return PR_SUCCESS;
215 } 215 }
216 216
217 NSS_IMPLEMENT PRStatus 217 NSS_IMPLEMENT PRStatus
218 nssList_Add(nssList *list, void *data) 218 nssList_Add(nssList *list, void *data)
219 { 219 {
220 NSSLIST_LOCK_IF(list); 220 NSSLIST_LOCK_IF(list);
221 (void)nsslist_add_element(list, data); 221 (void)nsslist_add_element(list, data);
222 NSSLIST_UNLOCK_IF(list); 222 NSSLIST_UNLOCK_IF(list);
223 return PR_SUCCESS; 223 return PR_SUCCESS;
224 } 224 }
225 225
226 NSS_IMPLEMENT PRStatus 226 NSS_IMPLEMENT PRStatus
227 nssList_AddUnique(nssList *list, void *data) 227 nssList_AddUnique(nssList *list, void *data)
228 { 228 {
229 PRStatus nssrv; 229 PRStatus nssrv;
230 nssListElement *node; 230 nssListElement *node;
231 NSSLIST_LOCK_IF(list); 231 NSSLIST_LOCK_IF(list);
232 node = nsslist_get_matching_element(list, data); 232 node = nsslist_get_matching_element(list, data);
233 if (node) { 233 if (node) {
234 » /* already in, finish */ 234 /* already in, finish */
235 » NSSLIST_UNLOCK_IF(list); 235 NSSLIST_UNLOCK_IF(list);
236 » return PR_SUCCESS; 236 return PR_SUCCESS;
237 } 237 }
238 nssrv = nsslist_add_element(list, data); 238 nssrv = nsslist_add_element(list, data);
239 NSSLIST_UNLOCK_IF(list); 239 NSSLIST_UNLOCK_IF(list);
240 return nssrv; 240 return nssrv;
241 } 241 }
242 242
243 NSS_IMPLEMENT PRStatus 243 NSS_IMPLEMENT PRStatus
244 nssList_Remove(nssList *list, void *data) 244 nssList_Remove(nssList *list, void *data)
245 { 245 {
246 nssListElement *node; 246 nssListElement *node;
247 NSSLIST_LOCK_IF(list); 247 NSSLIST_LOCK_IF(list);
248 node = nsslist_get_matching_element(list, data); 248 node = nsslist_get_matching_element(list, data);
249 if (node) { 249 if (node) {
250 » if (node == list->head) { 250 if (node == list->head) {
251 » list->head = (nssListElement *)PR_NEXT_LINK(&node->link); 251 list->head = (nssListElement *)PR_NEXT_LINK(&node->link);
252 » } 252 }
253 » PR_REMOVE_LINK(&node->link); 253 PR_REMOVE_LINK(&node->link);
254 » nss_ZFreeIf(node); 254 nss_ZFreeIf(node);
255 » if (--list->count == 0) { 255 if (--list->count == 0) {
256 » list->head = NULL; 256 list->head = NULL;
257 » } 257 }
258 } 258 }
259 NSSLIST_UNLOCK_IF(list); 259 NSSLIST_UNLOCK_IF(list);
260 return PR_SUCCESS; 260 return PR_SUCCESS;
261 } 261 }
262 262
263 NSS_IMPLEMENT void * 263 NSS_IMPLEMENT void *
264 nssList_Get(nssList *list, void *data) 264 nssList_Get(nssList *list, void *data)
265 { 265 {
266 nssListElement *node; 266 nssListElement *node;
267 NSSLIST_LOCK_IF(list); 267 NSSLIST_LOCK_IF(list);
268 node = nsslist_get_matching_element(list, data); 268 node = nsslist_get_matching_element(list, data);
269 NSSLIST_UNLOCK_IF(list); 269 NSSLIST_UNLOCK_IF(list);
270 return (node) ? node->data : NULL; 270 return (node) ? node->data : NULL;
271 } 271 }
272 272
273 NSS_IMPLEMENT PRUint32 273 NSS_IMPLEMENT PRUint32
274 nssList_Count(nssList *list) 274 nssList_Count(nssList *list)
275 { 275 {
276 return list->count; 276 return list->count;
277 } 277 }
278 278
279 NSS_IMPLEMENT PRStatus 279 NSS_IMPLEMENT PRStatus
280 nssList_GetArray(nssList *list, void **rvArray, PRUint32 maxElements) 280 nssList_GetArray(nssList *list, void **rvArray, PRUint32 maxElements)
281 { 281 {
282 nssListElement *node; 282 nssListElement *node;
283 PRUint32 i = 0; 283 PRUint32 i = 0;
284 PR_ASSERT(maxElements > 0); 284 PR_ASSERT(maxElements > 0);
285 node = list->head; 285 node = list->head;
286 if (!node) { 286 if (!node) {
287 » return PR_SUCCESS; 287 return PR_SUCCESS;
288 } 288 }
289 NSSLIST_LOCK_IF(list); 289 NSSLIST_LOCK_IF(list);
290 while (node) { 290 while (node) {
291 » rvArray[i++] = node->data; 291 rvArray[i++] = node->data;
292 » if (i == maxElements) break; 292 if (i == maxElements)
293 » node = (nssListElement *)PR_NEXT_LINK(&node->link); 293 break;
294 » if (node == list->head) { 294 node = (nssListElement *)PR_NEXT_LINK(&node->link);
295 » break; 295 if (node == list->head) {
296 » } 296 break;
297 }
297 } 298 }
298 NSSLIST_UNLOCK_IF(list); 299 NSSLIST_UNLOCK_IF(list);
299 return PR_SUCCESS; 300 return PR_SUCCESS;
300 } 301 }
301 302
302 NSS_IMPLEMENT nssList * 303 NSS_IMPLEMENT nssList *
303 nssList_Clone(nssList *list) 304 nssList_Clone(nssList *list)
304 { 305 {
305 nssList *rvList; 306 nssList *rvList;
306 nssListElement *node; 307 nssListElement *node;
307 rvList = nssList_Create(NULL, (list->lock != NULL)); 308 rvList = nssList_Create(NULL, (list->lock != NULL));
308 if (!rvList) { 309 if (!rvList) {
309 » return NULL; 310 return NULL;
310 } 311 }
311 NSSLIST_LOCK_IF(list); 312 NSSLIST_LOCK_IF(list);
312 if (list->count > 0) { 313 if (list->count > 0) {
313 » node = list->head; 314 node = list->head;
314 » while (PR_TRUE) { 315 while (PR_TRUE) {
315 » nssList_Add(rvList, node->data); 316 nssList_Add(rvList, node->data);
316 » node = (nssListElement *)PR_NEXT_LINK(&node->link); 317 node = (nssListElement *)PR_NEXT_LINK(&node->link);
317 » if (node == list->head) { 318 if (node == list->head) {
318 » » break; 319 break;
319 » } 320 }
320 » } 321 }
321 } 322 }
322 NSSLIST_UNLOCK_IF(list); 323 NSSLIST_UNLOCK_IF(list);
323 return rvList; 324 return rvList;
324 } 325 }
325 326
326 NSS_IMPLEMENT nssListIterator * 327 NSS_IMPLEMENT nssListIterator *
327 nssList_CreateIterator(nssList *list) 328 nssList_CreateIterator(nssList *list)
328 { 329 {
329 nssListIterator *rvIterator; 330 nssListIterator *rvIterator;
330 rvIterator = nss_ZNEW(NULL, nssListIterator); 331 rvIterator = nss_ZNEW(NULL, nssListIterator);
331 if (!rvIterator) { 332 if (!rvIterator) {
332 » return NULL; 333 return NULL;
333 } 334 }
334 rvIterator->list = nssList_Clone(list); 335 rvIterator->list = nssList_Clone(list);
335 if (!rvIterator->list) { 336 if (!rvIterator->list) {
336 » nss_ZFreeIf(rvIterator); 337 nss_ZFreeIf(rvIterator);
337 » return NULL; 338 return NULL;
338 } 339 }
339 rvIterator->current = rvIterator->list->head; 340 rvIterator->current = rvIterator->list->head;
340 if (list->lock) { 341 if (list->lock) {
341 » rvIterator->lock = PZ_NewLock(nssILockOther); 342 rvIterator->lock = PZ_NewLock(nssILockOther);
342 » if (!rvIterator->lock) { 343 if (!rvIterator->lock) {
343 » nssList_Destroy(rvIterator->list); 344 nssList_Destroy(rvIterator->list);
344 » nss_ZFreeIf(rvIterator); 345 nss_ZFreeIf(rvIterator);
345 » rvIterator = NULL; 346 rvIterator = NULL;
346 » } 347 }
347 } 348 }
348 return rvIterator; 349 return rvIterator;
349 } 350 }
350 351
351 NSS_IMPLEMENT void 352 NSS_IMPLEMENT void
352 nssListIterator_Destroy(nssListIterator *iter) 353 nssListIterator_Destroy(nssListIterator *iter)
353 { 354 {
354 if (iter->lock) { 355 if (iter->lock) {
355 » (void)PZ_DestroyLock(iter->lock); 356 (void)PZ_DestroyLock(iter->lock);
356 } 357 }
357 nssList_Destroy(iter->list); 358 nssList_Destroy(iter->list);
358 nss_ZFreeIf(iter); 359 nss_ZFreeIf(iter);
359 } 360 }
360 361
361 NSS_IMPLEMENT void * 362 NSS_IMPLEMENT void *
362 nssListIterator_Start(nssListIterator *iter) 363 nssListIterator_Start(nssListIterator *iter)
363 { 364 {
364 NSSLIST_LOCK_IF(iter); 365 NSSLIST_LOCK_IF(iter);
365 if (iter->list->count == 0) { 366 if (iter->list->count == 0) {
366 » return NULL; 367 return NULL;
367 } 368 }
368 iter->current = iter->list->head; 369 iter->current = iter->list->head;
369 return iter->current->data; 370 return iter->current->data;
370 } 371 }
371 372
372 NSS_IMPLEMENT void * 373 NSS_IMPLEMENT void *
373 nssListIterator_Next(nssListIterator *iter) 374 nssListIterator_Next(nssListIterator *iter)
374 { 375 {
375 nssListElement *node; 376 nssListElement *node;
376 PRCList *link; 377 PRCList *link;
377 if (iter->list->count == 1 || iter->current == NULL) { 378 if (iter->list->count == 1 || iter->current == NULL) {
378 » /* Reached the end of the list. Don't change the state, force to 379 /* Reached the end of the list. Don't change the state, force to
379 » * user to call nssList_Finish to clean up. 380 * user to call nssList_Finish to clean up.
380 » */ 381 */
381 » return NULL; 382 return NULL;
382 } 383 }
383 node = (nssListElement *)PR_NEXT_LINK(&iter->current->link); 384 node = (nssListElement *)PR_NEXT_LINK(&iter->current->link);
384 link = &node->link; 385 link = &node->link;
385 if (link == PR_LIST_TAIL(&iter->list->head->link)) { 386 if (link == PR_LIST_TAIL(&iter->list->head->link)) {
386 » /* Signal the end of the list. */ 387 /* Signal the end of the list. */
387 » iter->current = NULL; 388 iter->current = NULL;
388 » return node->data; 389 return node->data;
389 } 390 }
390 iter->current = node; 391 iter->current = node;
391 return node->data; 392 return node->data;
392 } 393 }
393 394
394 NSS_IMPLEMENT PRStatus 395 NSS_IMPLEMENT PRStatus
395 nssListIterator_Finish(nssListIterator *iter) 396 nssListIterator_Finish(nssListIterator *iter)
396 { 397 {
397 iter->current = iter->list->head; 398 iter->current = iter->list->head;
398 return (iter->lock) ? PZ_Unlock(iter->lock) : PR_SUCCESS; 399 return (iter->lock) ? PZ_Unlock(iter->lock) : PR_SUCCESS;
399 } 400 }
400
OLDNEW
« no previous file with comments | « nss/lib/base/libc.c ('k') | nss/lib/base/nssbase.h » ('j') | nss/lib/util/secoid.c » ('J')

Powered by Google App Engine
This is Rietveld 408576698