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 * 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 Loading... |
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 | |
OLD | NEW |