| 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 |