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

Side by Side Diff: nss/lib/base/arena.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 * arena.c 6 * arena.c
7 * 7 *
8 * This contains the implementation of NSS's thread-safe arenas. 8 * This contains the implementation of NSS's thread-safe arenas.
9 */ 9 */
10 10
(...skipping 23 matching lines...) Expand all
34 * NSS_ZRealloc 34 * NSS_ZRealloc
35 * NSS_ZFreeIf 35 * NSS_ZFreeIf
36 * 36 *
37 * The nonpublic methods relating to this type are: 37 * The nonpublic methods relating to this type are:
38 * 38 *
39 * nssArena_Create -- constructor 39 * nssArena_Create -- constructor
40 * nssArena_Destroy 40 * nssArena_Destroy
41 * nssArena_Mark 41 * nssArena_Mark
42 * nssArena_Release 42 * nssArena_Release
43 * nssArena_Unmark 43 * nssArena_Unmark
44 * 44 *
45 * nss_ZAlloc 45 * nss_ZAlloc
46 * nss_ZFreeIf 46 * nss_ZFreeIf
47 * nss_ZRealloc 47 * nss_ZRealloc
48 * 48 *
49 * In debug builds, the following calls are available: 49 * In debug builds, the following calls are available:
50 * 50 *
51 * nssArena_verifyPointer 51 * nssArena_verifyPointer
52 * nssArena_registerDestructor 52 * nssArena_registerDestructor
53 * nssArena_deregisterDestructor 53 * nssArena_deregisterDestructor
54 */ 54 */
55 55
56 struct NSSArenaStr { 56 struct NSSArenaStr {
57 PLArenaPool pool; 57 PLArenaPool pool;
58 PRLock *lock; 58 PRLock *lock;
59 #ifdef ARENA_THREADMARK 59 #ifdef ARENA_THREADMARK
60 PRThread *marking_thread; 60 PRThread *marking_thread;
61 nssArenaMark *first_mark; 61 nssArenaMark *first_mark;
62 nssArenaMark *last_mark; 62 nssArenaMark *last_mark;
63 #endif /* ARENA_THREADMARK */ 63 #endif /* ARENA_THREADMARK */
64 #ifdef ARENA_DESTRUCTOR_LIST 64 #ifdef ARENA_DESTRUCTOR_LIST
65 struct arena_destructor_node *first_destructor; 65 struct arena_destructor_node *first_destructor;
66 struct arena_destructor_node *last_destructor; 66 struct arena_destructor_node *last_destructor;
67 #endif /* ARENA_DESTRUCTOR_LIST */ 67 #endif /* ARENA_DESTRUCTOR_LIST */
68 }; 68 };
69 69
70 /* 70 /*
71 * nssArenaMark 71 * nssArenaMark
72 * 72 *
73 * This type is used to mark the current state of an NSSArena. 73 * This type is used to mark the current state of an NSSArena.
74 */ 74 */
75 75
76 struct nssArenaMarkStr { 76 struct nssArenaMarkStr {
77 PRUint32 magic; 77 PRUint32 magic;
78 void *mark; 78 void *mark;
79 #ifdef ARENA_THREADMARK 79 #ifdef ARENA_THREADMARK
80 nssArenaMark *next; 80 nssArenaMark *next;
81 #endif /* ARENA_THREADMARK */ 81 #endif /* ARENA_THREADMARK */
82 #ifdef ARENA_DESTRUCTOR_LIST 82 #ifdef ARENA_DESTRUCTOR_LIST
83 struct arena_destructor_node *next_destructor; 83 struct arena_destructor_node *next_destructor;
84 struct arena_destructor_node *prev_destructor; 84 struct arena_destructor_node *prev_destructor;
85 #endif /* ARENA_DESTRUCTOR_LIST */ 85 #endif /* ARENA_DESTRUCTOR_LIST */
86 }; 86 };
87 87
88 #define MARK_MAGIC 0x4d41524b /* "MARK" how original */ 88 #define MARK_MAGIC 0x4d41524b /* "MARK" how original */
89 89
90 /* 90 /*
91 * But first, the pointer-tracking code 91 * But first, the pointer-tracking code
92 */ 92 */
93 #ifdef DEBUG 93 #ifdef DEBUG
94 extern const NSSError NSS_ERROR_INTERNAL_ERROR; 94 extern const NSSError NSS_ERROR_INTERNAL_ERROR;
95 95
96 static nssPointerTracker arena_pointer_tracker; 96 static nssPointerTracker arena_pointer_tracker;
97 97
98 static PRStatus 98 static PRStatus
99 arena_add_pointer 99 arena_add_pointer(const NSSArena *arena)
100 (
101 const NSSArena *arena
102 )
103 { 100 {
104 PRStatus rv; 101 PRStatus rv;
105 102
106 rv = nssPointerTracker_initialize(&arena_pointer_tracker); 103 rv = nssPointerTracker_initialize(&arena_pointer_tracker);
107 if( PR_SUCCESS != rv ) { 104 if (PR_SUCCESS != rv) {
108 return rv; 105 return rv;
109 } 106 }
110 107
111 rv = nssPointerTracker_add(&arena_pointer_tracker, arena); 108 rv = nssPointerTracker_add(&arena_pointer_tracker, arena);
112 if( PR_SUCCESS != rv ) { 109 if (PR_SUCCESS != rv) {
113 NSSError e = NSS_GetError(); 110 NSSError e = NSS_GetError();
114 if( NSS_ERROR_NO_MEMORY != e ) { 111 if (NSS_ERROR_NO_MEMORY != e) {
115 nss_SetError(NSS_ERROR_INTERNAL_ERROR); 112 nss_SetError(NSS_ERROR_INTERNAL_ERROR);
113 }
114
115 return rv;
116 }
117
118 return PR_SUCCESS;
119 }
120
121 static PRStatus
122 arena_remove_pointer(const NSSArena *arena)
123 {
124 PRStatus rv;
125
126 rv = nssPointerTracker_remove(&arena_pointer_tracker, arena);
127 if (PR_SUCCESS != rv) {
128 nss_SetError(NSS_ERROR_INTERNAL_ERROR);
116 } 129 }
117 130
118 return rv; 131 return rv;
119 }
120
121 return PR_SUCCESS;
122 }
123
124 static PRStatus
125 arena_remove_pointer
126 (
127 const NSSArena *arena
128 )
129 {
130 PRStatus rv;
131
132 rv = nssPointerTracker_remove(&arena_pointer_tracker, arena);
133 if( PR_SUCCESS != rv ) {
134 nss_SetError(NSS_ERROR_INTERNAL_ERROR);
135 }
136
137 return rv;
138 } 132 }
139 133
140 /* 134 /*
141 * nssArena_verifyPointer 135 * nssArena_verifyPointer
142 * 136 *
143 * This method is only present in debug builds. 137 * This method is only present in debug builds.
144 * 138 *
145 * If the specified pointer is a valid pointer to an NSSArena object, 139 * If the specified pointer is a valid pointer to an NSSArena object,
146 * this routine will return PR_SUCCESS. Otherwise, it will put an 140 * this routine will return PR_SUCCESS. Otherwise, it will put an
147 * error on the error stack and return PR_FAILURE. 141 * error on the error stack and return PR_FAILURE.
148 * 142 *
149 * The error may be one of the following values: 143 * The error may be one of the following values:
150 * NSS_ERROR_INVALID_ARENA 144 * NSS_ERROR_INVALID_ARENA
151 * 145 *
152 * Return value: 146 * Return value:
153 * PR_SUCCESS if the pointer is valid 147 * PR_SUCCESS if the pointer is valid
154 * PR_FAILURE if it isn't 148 * PR_FAILURE if it isn't
155 */ 149 */
156 150
157 NSS_IMPLEMENT PRStatus 151 NSS_IMPLEMENT PRStatus
158 nssArena_verifyPointer 152 nssArena_verifyPointer(const NSSArena *arena)
159 (
160 const NSSArena *arena
161 )
162 { 153 {
163 PRStatus rv; 154 PRStatus rv;
164 155
165 rv = nssPointerTracker_initialize(&arena_pointer_tracker); 156 rv = nssPointerTracker_initialize(&arena_pointer_tracker);
166 if( PR_SUCCESS != rv ) { 157 if (PR_SUCCESS != rv) {
167 /* 158 /*
168 * This is a little disingenious. We have to initialize the 159 * This is a little disingenious. We have to initialize the
169 * tracker, because someone could "legitimately" try to verify 160 * tracker, because someone could "legitimately" try to verify
170 * an arena pointer before one is ever created. And this step 161 * an arena pointer before one is ever created. And this step
171 * might fail, due to lack of memory. But the only way that 162 * might fail, due to lack of memory. But the only way that
172 * this step can fail is if it's doing the call_once stuff, 163 * this step can fail is if it's doing the call_once stuff,
173 * (later calls just no-op). And if it didn't no-op, there 164 * (later calls just no-op). And if it didn't no-op, there
174 * aren't any valid arenas.. so the argument certainly isn't one. 165 * aren't any valid arenas.. so the argument certainly isn't one.
175 */ 166 */
176 nss_SetError(NSS_ERROR_INVALID_ARENA); 167 nss_SetError(NSS_ERROR_INVALID_ARENA);
177 return PR_FAILURE; 168 return PR_FAILURE;
178 } 169 }
179 170
180 rv = nssPointerTracker_verify(&arena_pointer_tracker, arena); 171 rv = nssPointerTracker_verify(&arena_pointer_tracker, arena);
181 if( PR_SUCCESS != rv ) { 172 if (PR_SUCCESS != rv) {
182 nss_SetError(NSS_ERROR_INVALID_ARENA); 173 nss_SetError(NSS_ERROR_INVALID_ARENA);
183 return PR_FAILURE; 174 return PR_FAILURE;
184 } 175 }
185 176
186 return PR_SUCCESS; 177 return PR_SUCCESS;
187 } 178 }
188 #endif /* DEBUG */ 179 #endif /* DEBUG */
189 180
190 #ifdef ARENA_DESTRUCTOR_LIST 181 #ifdef ARENA_DESTRUCTOR_LIST
191 182
192 struct arena_destructor_node { 183 struct arena_destructor_node {
193 struct arena_destructor_node *next; 184 struct arena_destructor_node *next;
194 struct arena_destructor_node *prev; 185 struct arena_destructor_node *prev;
195 void (*destructor)(void *argument); 186 void (*destructor)(void *argument);
196 void *arg; 187 void *arg;
197 }; 188 };
198 189
199 /* 190 /*
200 * nssArena_registerDestructor 191 * nssArena_registerDestructor
201 * 192 *
202 * This routine stores a pointer to a callback and an arbitrary 193 * This routine stores a pointer to a callback and an arbitrary
203 * pointer-sized argument in the arena, at the current point in 194 * pointer-sized argument in the arena, at the current point in
204 * the mark stack. If the arena is destroyed, or an "earlier" 195 * the mark stack. If the arena is destroyed, or an "earlier"
205 * mark is released, then this destructor will be called at that 196 * mark is released, then this destructor will be called at that
206 * time. Note that the destructor will be called with the arena 197 * time. Note that the destructor will be called with the arena
207 * locked, which means the destructor may free memory in that 198 * locked, which means the destructor may free memory in that
208 * arena, but it may not allocate or cause to be allocated any 199 * arena, but it may not allocate or cause to be allocated any
209 * memory. This callback facility was included to support our 200 * memory. This callback facility was included to support our
210 * debug-version pointer-tracker feature; overuse runs counter to 201 * debug-version pointer-tracker feature; overuse runs counter to
211 * the the original intent of arenas. This routine returns a 202 * the the original intent of arenas. This routine returns a
212 * PRStatus value; if successful, it will return PR_SUCCESS. If 203 * PRStatus value; if successful, it will return PR_SUCCESS. If
213 * unsuccessful, it will set an error on the error stack and 204 * unsuccessful, it will set an error on the error stack and
214 * return PR_FAILURE. 205 * return PR_FAILURE.
215 * 206 *
216 * The error may be one of the following values: 207 * The error may be one of the following values:
217 * NSS_ERROR_INVALID_ARENA 208 * NSS_ERROR_INVALID_ARENA
218 * NSS_ERROR_NO_MEMORY 209 * NSS_ERROR_NO_MEMORY
219 * 210 *
220 * Return value: 211 * Return value:
221 * PR_SUCCESS 212 * PR_SUCCESS
222 * PR_FAILURE 213 * PR_FAILURE
223 */ 214 */
224 215
225 NSS_IMPLEMENT PRStatus 216 NSS_IMPLEMENT PRStatus
226 nssArena_registerDestructor 217 nssArena_registerDestructor(NSSArena *arena, void (*destructor)(void *argument),
227 ( 218 void *arg)
228 NSSArena *arena,
229 void (*destructor)(void *argument),
230 void *arg
231 )
232 { 219 {
233 struct arena_destructor_node *it; 220 struct arena_destructor_node *it;
234 221
235 #ifdef NSSDEBUG 222 #ifdef NSSDEBUG
236 if( PR_SUCCESS != nssArena_verifyPointer(arena) ) { 223 if (PR_SUCCESS != nssArena_verifyPointer(arena)) {
237 return PR_FAILURE; 224 return PR_FAILURE;
238 } 225 }
239 #endif /* NSSDEBUG */ 226 #endif /* NSSDEBUG */
240
241 it = nss_ZNEW(arena, struct arena_destructor_node);
242 if( (struct arena_destructor_node *)NULL == it ) {
243 return PR_FAILURE;
244 }
245 227
246 it->prev = arena->last_destructor; 228 it = nss_ZNEW(arena, struct arena_destructor_node);
247 arena->last_destructor->next = it; 229 if ((struct arena_destructor_node *)NULL == it) {
248 arena->last_destructor = it; 230 return PR_FAILURE;
249 it->destructor = destructor; 231 }
250 it->arg = arg;
251 232
252 if( (nssArenaMark *)NULL != arena->last_mark ) { 233 it->prev = arena->last_destructor;
253 arena->last_mark->prev_destructor = it->prev; 234 arena->last_destructor->next = it;
254 arena->last_mark->next_destructor = it->next; 235 arena->last_destructor = it;
255 } 236 it->destructor = destructor;
237 it->arg = arg;
256 238
257 return PR_SUCCESS; 239 if ((nssArenaMark *)NULL != arena->last_mark) {
240 arena->last_mark->prev_destructor = it->prev;
241 arena->last_mark->next_destructor = it->next;
242 }
243
244 return PR_SUCCESS;
258 } 245 }
259 246
260 NSS_IMPLEMENT PRStatus 247 NSS_IMPLEMENT PRStatus
261 nssArena_deregisterDestructor 248 nssArena_deregisterDestructor(NSSArena *arena,
262 ( 249 void (*destructor)(void *argument), void *arg)
263 NSSArena *arena,
264 void (*destructor)(void *argument),
265 void *arg
266 )
267 { 250 {
268 struct arena_destructor_node *it; 251 struct arena_destructor_node *it;
269 252
270 #ifdef NSSDEBUG 253 #ifdef NSSDEBUG
271 if( PR_SUCCESS != nssArena_verifyPointer(arena) ) { 254 if (PR_SUCCESS != nssArena_verifyPointer(arena)) {
272 return PR_FAILURE; 255 return PR_FAILURE;
273 } 256 }
274 #endif /* NSSDEBUG */ 257 #endif /* NSSDEBUG */
275 258
276 for( it = arena->first_destructor; it; it = it->next ) { 259 for (it = arena->first_destructor; it; it = it->next) {
277 if( (it->destructor == destructor) && (it->arg == arg) ) { 260 if ((it->destructor == destructor) && (it->arg == arg)) {
278 break; 261 break;
262 }
279 } 263 }
280 }
281 264
282 if( (struct arena_destructor_node *)NULL == it ) { 265 if ((struct arena_destructor_node *)NULL == it) {
283 nss_SetError(NSS_ERROR_NOT_FOUND); 266 nss_SetError(NSS_ERROR_NOT_FOUND);
284 return PR_FAILURE; 267 return PR_FAILURE;
285 } 268 }
286 269
287 if( it == arena->first_destructor ) { 270 if (it == arena->first_destructor) {
288 arena->first_destructor = it->next; 271 arena->first_destructor = it->next;
289 } 272 }
290 273
291 if( it == arena->last_destructor ) { 274 if (it == arena->last_destructor) {
292 arena->last_destructor = it->prev; 275 arena->last_destructor = it->prev;
293 } 276 }
294 277
295 if( (struct arena_destructor_node *)NULL != it->prev ) { 278 if ((struct arena_destructor_node *)NULL != it->prev) {
296 it->prev->next = it->next; 279 it->prev->next = it->next;
297 } 280 }
298 281
299 if( (struct arena_destructor_node *)NULL != it->next ) { 282 if ((struct arena_destructor_node *)NULL != it->next) {
300 it->next->prev = it->prev; 283 it->next->prev = it->prev;
301 } 284 }
302 285
303 { 286 {
304 nssArenaMark *m; 287 nssArenaMark *m;
305 for( m = arena->first_mark; m; m = m->next ) { 288 for (m = arena->first_mark; m; m = m->next) {
306 if( m->next_destructor == it ) { 289 if (m->next_destructor == it) {
307 m->next_destructor = it->next; 290 m->next_destructor = it->next;
308 } 291 }
309 if( m->prev_destructor == it ) { 292 if (m->prev_destructor == it) {
310 m->prev_destructor = it->prev; 293 m->prev_destructor = it->prev;
311 } 294 }
295 }
312 } 296 }
313 }
314 297
315 nss_ZFreeIf(it); 298 nss_ZFreeIf(it);
316 return PR_SUCCESS; 299 return PR_SUCCESS;
317 } 300 }
318 301
319 static void 302 static void
320 nss_arena_call_destructor_chain 303 nss_arena_call_destructor_chain(struct arena_destructor_node *it)
321 (
322 struct arena_destructor_node *it
323 )
324 { 304 {
325 for( ; it ; it = it->next ) { 305 for (; it; it = it->next) {
326 (*(it->destructor))(it->arg); 306 (*(it->destructor))(it->arg);
327 } 307 }
328 } 308 }
329 309
330 #endif /* ARENA_DESTRUCTOR_LIST */ 310 #endif /* ARENA_DESTRUCTOR_LIST */
331 311
332 /* 312 /*
333 * NSSArena_Create 313 * NSSArena_Create
334 * 314 *
335 * This routine creates a new memory arena. This routine may return 315 * This routine creates a new memory arena. This routine may return
336 * NULL upon error, in which case it will have created an error stack. 316 * NULL upon error, in which case it will have created an error stack.
337 * 317 *
338 * The top-level error may be one of the following values: 318 * The top-level error may be one of the following values:
339 * NSS_ERROR_NO_MEMORY 319 * NSS_ERROR_NO_MEMORY
340 * 320 *
341 * Return value: 321 * Return value:
342 * NULL upon error 322 * NULL upon error
343 * A pointer to an NSSArena upon success 323 * A pointer to an NSSArena upon success
344 */ 324 */
345 325
346 NSS_IMPLEMENT NSSArena * 326 NSS_IMPLEMENT NSSArena *
347 NSSArena_Create 327 NSSArena_Create(void)
348 (
349 void
350 )
351 { 328 {
352 nss_ClearErrorStack(); 329 nss_ClearErrorStack();
353 return nssArena_Create(); 330 return nssArena_Create();
354 } 331 }
355 332
356 /* 333 /*
357 * nssArena_Create 334 * nssArena_Create
358 * 335 *
359 * This routine creates a new memory arena. This routine may return 336 * This routine creates a new memory arena. This routine may return
360 * NULL upon error, in which case it will have set an error on the 337 * NULL upon error, in which case it will have set an error on the
361 * error stack. 338 * error stack.
362 * 339 *
363 * The error may be one of the following values: 340 * The error may be one of the following values:
364 * NSS_ERROR_NO_MEMORY 341 * NSS_ERROR_NO_MEMORY
365 * 342 *
366 * Return value: 343 * Return value:
367 * NULL upon error 344 * NULL upon error
368 * A pointer to an NSSArena upon success 345 * A pointer to an NSSArena upon success
369 */ 346 */
370 347
371 NSS_IMPLEMENT NSSArena * 348 NSS_IMPLEMENT NSSArena *
372 nssArena_Create 349 nssArena_Create(void)
373 (
374 void
375 )
376 { 350 {
377 NSSArena *rv = (NSSArena *)NULL; 351 NSSArena *rv = (NSSArena *)NULL;
378 352
379 rv = nss_ZNEW((NSSArena *)NULL, NSSArena); 353 rv = nss_ZNEW((NSSArena *)NULL, NSSArena);
380 if( (NSSArena *)NULL == rv ) { 354 if ((NSSArena *)NULL == rv) {
381 nss_SetError(NSS_ERROR_NO_MEMORY); 355 nss_SetError(NSS_ERROR_NO_MEMORY);
382 return (NSSArena *)NULL; 356 return (NSSArena *)NULL;
383 } 357 }
384 358
385 rv->lock = PR_NewLock(); 359 rv->lock = PR_NewLock();
386 if( (PRLock *)NULL == rv->lock ) { 360 if ((PRLock *)NULL == rv->lock) {
387 (void)nss_ZFreeIf(rv); 361 (void)nss_ZFreeIf(rv);
388 nss_SetError(NSS_ERROR_NO_MEMORY); 362 nss_SetError(NSS_ERROR_NO_MEMORY);
389 return (NSSArena *)NULL; 363 return (NSSArena *)NULL;
390 } 364 }
391 365
392 /* 366 /*
393 * Arena sizes. The current security code has 229 occurrences of 367 * Arena sizes. The current security code has 229 occurrences of
394 * PORT_NewArena. The default chunksizes specified break down as 368 * PORT_NewArena. The default chunksizes specified break down as
395 * 369 *
396 * Size Mult. Specified as 370 * Size Mult. Specified as
397 * 512 1 512 371 * 512 1 512
398 * 1024 7 1024 372 * 1024 7 1024
399 * 2048 5 2048 373 * 2048 5 2048
400 * 2048 5 CRMF_DEFAULT_ARENA_SIZE 374 * 2048 5 CRMF_DEFAULT_ARENA_SIZE
401 * 2048 190 DER_DEFAULT_CHUNKSIZE 375 * 2048 190 DER_DEFAULT_CHUNKSIZE
402 * 2048 20 SEC_ASN1_DEFAULT_ARENA_SIZE 376 * 2048 20 SEC_ASN1_DEFAULT_ARENA_SIZE
403 * 4096 1 4096 377 * 4096 1 4096
404 * 378 *
405 * Obviously this "default chunksize" flexibility isn't very 379 * Obviously this "default chunksize" flexibility isn't very
406 * useful to us, so I'll just pick 2048. 380 * useful to us, so I'll just pick 2048.
407 */ 381 */
408 382
409 PL_InitArenaPool(&rv->pool, "NSS", 2048, sizeof(double)); 383 PL_InitArenaPool(&rv->pool, "NSS", 2048, sizeof(double));
410 384
411 #ifdef DEBUG 385 #ifdef DEBUG
412 { 386 {
413 PRStatus st; 387 PRStatus st;
414 st = arena_add_pointer(rv); 388 st = arena_add_pointer(rv);
415 if( PR_SUCCESS != st ) { 389 if (PR_SUCCESS != st) {
416 PL_FinishArenaPool(&rv->pool); 390 PL_FinishArenaPool(&rv->pool);
417 PR_DestroyLock(rv->lock); 391 PR_DestroyLock(rv->lock);
418 (void)nss_ZFreeIf(rv); 392 (void)nss_ZFreeIf(rv);
419 return (NSSArena *)NULL; 393 return (NSSArena *)NULL;
394 }
420 } 395 }
421 }
422 #endif /* DEBUG */ 396 #endif /* DEBUG */
423 397
424 return rv; 398 return rv;
425 } 399 }
426 400
427 /* 401 /*
428 * NSSArena_Destroy 402 * NSSArena_Destroy
429 * 403 *
430 * This routine will destroy the specified arena, freeing all memory 404 * This routine will destroy the specified arena, freeing all memory
431 * allocated from it. This routine returns a PRStatus value; if 405 * allocated from it. This routine returns a PRStatus value; if
432 * successful, it will return PR_SUCCESS. If unsuccessful, it will 406 * successful, it will return PR_SUCCESS. If unsuccessful, it will
433 * create an error stack and return PR_FAILURE. 407 * create an error stack and return PR_FAILURE.
434 * 408 *
435 * The top-level error may be one of the following values: 409 * The top-level error may be one of the following values:
436 * NSS_ERROR_INVALID_ARENA 410 * NSS_ERROR_INVALID_ARENA
437 * 411 *
438 * Return value: 412 * Return value:
439 * PR_SUCCESS upon success 413 * PR_SUCCESS upon success
440 * PR_FAILURE upon failure 414 * PR_FAILURE upon failure
441 */ 415 */
442 416
443 NSS_IMPLEMENT PRStatus 417 NSS_IMPLEMENT PRStatus
444 NSSArena_Destroy 418 NSSArena_Destroy(NSSArena *arena)
445 (
446 NSSArena *arena
447 )
448 { 419 {
449 nss_ClearErrorStack(); 420 nss_ClearErrorStack();
450 421
451 #ifdef DEBUG 422 #ifdef DEBUG
452 if( PR_SUCCESS != nssArena_verifyPointer(arena) ) { 423 if (PR_SUCCESS != nssArena_verifyPointer(arena)) {
453 return PR_FAILURE; 424 return PR_FAILURE;
454 } 425 }
455 #endif /* DEBUG */ 426 #endif /* DEBUG */
456 427
457 return nssArena_Destroy(arena); 428 return nssArena_Destroy(arena);
458 } 429 }
459 430
460 /* 431 /*
461 * nssArena_Destroy 432 * nssArena_Destroy
462 * 433 *
463 * This routine will destroy the specified arena, freeing all memory 434 * This routine will destroy the specified arena, freeing all memory
464 * allocated from it. This routine returns a PRStatus value; if 435 * allocated from it. This routine returns a PRStatus value; if
465 * successful, it will return PR_SUCCESS. If unsuccessful, it will 436 * successful, it will return PR_SUCCESS. If unsuccessful, it will
466 * set an error on the error stack and return PR_FAILURE. 437 * set an error on the error stack and return PR_FAILURE.
467 * 438 *
468 * The error may be one of the following values: 439 * The error may be one of the following values:
469 * NSS_ERROR_INVALID_ARENA 440 * NSS_ERROR_INVALID_ARENA
470 * 441 *
471 * Return value: 442 * Return value:
472 * PR_SUCCESS 443 * PR_SUCCESS
473 * PR_FAILURE 444 * PR_FAILURE
474 */ 445 */
475 446
476 NSS_IMPLEMENT PRStatus 447 NSS_IMPLEMENT PRStatus
477 nssArena_Destroy 448 nssArena_Destroy(NSSArena *arena)
478 (
479 NSSArena *arena
480 )
481 { 449 {
482 PRLock *lock; 450 PRLock *lock;
483 451
484 #ifdef NSSDEBUG 452 #ifdef NSSDEBUG
485 if( PR_SUCCESS != nssArena_verifyPointer(arena) ) { 453 if (PR_SUCCESS != nssArena_verifyPointer(arena)) {
486 return PR_FAILURE; 454 return PR_FAILURE;
487 } 455 }
488 #endif /* NSSDEBUG */ 456 #endif /* NSSDEBUG */
489 457
490 if( (PRLock *)NULL == arena->lock ) { 458 if ((PRLock *)NULL == arena->lock) {
491 /* Just got destroyed */ 459 /* Just got destroyed */
492 nss_SetError(NSS_ERROR_INVALID_ARENA); 460 nss_SetError(NSS_ERROR_INVALID_ARENA);
493 return PR_FAILURE; 461 return PR_FAILURE;
494 } 462 }
495 PR_Lock(arena->lock); 463 PR_Lock(arena->lock);
496 464
497 #ifdef DEBUG 465 #ifdef DEBUG
498 if( PR_SUCCESS != arena_remove_pointer(arena) ) { 466 if (PR_SUCCESS != arena_remove_pointer(arena)) {
499 PR_Unlock(arena->lock); 467 PR_Unlock(arena->lock);
500 return PR_FAILURE; 468 return PR_FAILURE;
501 } 469 }
502 #endif /* DEBUG */ 470 #endif /* DEBUG */
503 471
504 #ifdef ARENA_DESTRUCTOR_LIST 472 #ifdef ARENA_DESTRUCTOR_LIST
505 /* Note that the arena is locked at this time */ 473 /* Note that the arena is locked at this time */
506 nss_arena_call_destructor_chain(arena->first_destructor); 474 nss_arena_call_destructor_chain(arena->first_destructor);
507 #endif /* ARENA_DESTRUCTOR_LIST */ 475 #endif /* ARENA_DESTRUCTOR_LIST */
508 476
509 PL_FinishArenaPool(&arena->pool); 477 PL_FinishArenaPool(&arena->pool);
510 lock = arena->lock; 478 lock = arena->lock;
511 arena->lock = (PRLock *)NULL; 479 arena->lock = (PRLock *)NULL;
512 PR_Unlock(lock); 480 PR_Unlock(lock);
513 PR_DestroyLock(lock); 481 PR_DestroyLock(lock);
514 (void)nss_ZFreeIf(arena); 482 (void)nss_ZFreeIf(arena);
515 return PR_SUCCESS; 483 return PR_SUCCESS;
516 } 484 }
517 485
518 static void *nss_zalloc_arena_locked(NSSArena *arena, PRUint32 size); 486 static void *nss_zalloc_arena_locked(NSSArena *arena, PRUint32 size);
519 487
520 /* 488 /*
521 * nssArena_Mark 489 * nssArena_Mark
522 * 490 *
523 * This routine "marks" the current state of an arena. Space 491 * This routine "marks" the current state of an arena. Space
524 * allocated after the arena has been marked can be freed by 492 * allocated after the arena has been marked can be freed by
525 * releasing the arena back to the mark with nssArena_Release, 493 * releasing the arena back to the mark with nssArena_Release,
526 * or committed by calling nssArena_Unmark. When successful, 494 * or committed by calling nssArena_Unmark. When successful,
527 * this routine returns a valid nssArenaMark pointer. This 495 * this routine returns a valid nssArenaMark pointer. This
528 * routine may return NULL upon error, in which case it will 496 * routine may return NULL upon error, in which case it will
529 * have set an error on the error stack. 497 * have set an error on the error stack.
530 * 498 *
531 * The error may be one of the following values: 499 * The error may be one of the following values:
532 * NSS_ERROR_INVALID_ARENA 500 * NSS_ERROR_INVALID_ARENA
533 * NSS_ERROR_NO_MEMORY 501 * NSS_ERROR_NO_MEMORY
534 * NSS_ERROR_ARENA_MARKED_BY_ANOTHER_THREAD 502 * NSS_ERROR_ARENA_MARKED_BY_ANOTHER_THREAD
535 * 503 *
536 * Return value: 504 * Return value:
537 * NULL upon failure 505 * NULL upon failure
538 * An nssArenaMark pointer upon success 506 * An nssArenaMark pointer upon success
539 */ 507 */
540 508
541 NSS_IMPLEMENT nssArenaMark * 509 NSS_IMPLEMENT nssArenaMark *
542 nssArena_Mark 510 nssArena_Mark(NSSArena *arena)
543 (
544 NSSArena *arena
545 )
546 { 511 {
547 nssArenaMark *rv; 512 nssArenaMark *rv;
548 void *p; 513 void *p;
549 514
550 #ifdef NSSDEBUG 515 #ifdef NSSDEBUG
551 if( PR_SUCCESS != nssArena_verifyPointer(arena) ) { 516 if (PR_SUCCESS != nssArena_verifyPointer(arena)) {
552 return (nssArenaMark *)NULL; 517 return (nssArenaMark *)NULL;
553 } 518 }
554 #endif /* NSSDEBUG */ 519 #endif /* NSSDEBUG */
555 520
556 if( (PRLock *)NULL == arena->lock ) { 521 if ((PRLock *)NULL == arena->lock) {
557 /* Just got destroyed */ 522 /* Just got destroyed */
558 nss_SetError(NSS_ERROR_INVALID_ARENA); 523 nss_SetError(NSS_ERROR_INVALID_ARENA);
559 return (nssArenaMark *)NULL; 524 return (nssArenaMark *)NULL;
560 } 525 }
561 PR_Lock(arena->lock); 526 PR_Lock(arena->lock);
562 527
563 #ifdef ARENA_THREADMARK 528 #ifdef ARENA_THREADMARK
564 if( (PRThread *)NULL == arena->marking_thread ) { 529 if ((PRThread *)NULL == arena->marking_thread) {
565 /* Unmarked. Store our thread ID */ 530 /* Unmarked. Store our thread ID */
566 arena->marking_thread = PR_GetCurrentThread(); 531 arena->marking_thread = PR_GetCurrentThread();
567 /* This call never fails. */ 532 /* This call never fails. */
568 } else { 533 } else {
569 /* Marked. Verify it's the current thread */ 534 /* Marked. Verify it's the current thread */
570 if( PR_GetCurrentThread() != arena->marking_thread ) { 535 if (PR_GetCurrentThread() != arena->marking_thread) {
571 PR_Unlock(arena->lock); 536 PR_Unlock(arena->lock);
572 nss_SetError(NSS_ERROR_ARENA_MARKED_BY_ANOTHER_THREAD); 537 nss_SetError(NSS_ERROR_ARENA_MARKED_BY_ANOTHER_THREAD);
573 return (nssArenaMark *)NULL; 538 return (nssArenaMark *)NULL;
539 }
574 } 540 }
575 }
576 #endif /* ARENA_THREADMARK */ 541 #endif /* ARENA_THREADMARK */
577 542
578 p = PL_ARENA_MARK(&arena->pool); 543 p = PL_ARENA_MARK(&arena->pool);
579 /* No error possible */ 544 /* No error possible */
580 545
581 /* Do this after the mark */ 546 /* Do this after the mark */
582 rv = (nssArenaMark *)nss_zalloc_arena_locked(arena, sizeof(nssArenaMark)); 547 rv = (nssArenaMark *)nss_zalloc_arena_locked(arena, sizeof(nssArenaMark));
583 if( (nssArenaMark *)NULL == rv ) { 548 if ((nssArenaMark *)NULL == rv) {
584 PR_Unlock(arena->lock); 549 PR_Unlock(arena->lock);
585 nss_SetError(NSS_ERROR_NO_MEMORY); 550 nss_SetError(NSS_ERROR_NO_MEMORY);
586 return (nssArenaMark *)NULL; 551 return (nssArenaMark *)NULL;
587 } 552 }
588 553
589 #ifdef ARENA_THREADMARK 554 #ifdef ARENA_THREADMARK
590 if ( (nssArenaMark *)NULL == arena->first_mark) { 555 if ((nssArenaMark *)NULL == arena->first_mark) {
591 arena->first_mark = rv; 556 arena->first_mark = rv;
592 arena->last_mark = rv; 557 arena->last_mark = rv;
593 } else { 558 } else {
594 arena->last_mark->next = rv; 559 arena->last_mark->next = rv;
595 arena->last_mark = rv; 560 arena->last_mark = rv;
596 } 561 }
597 #endif /* ARENA_THREADMARK */ 562 #endif /* ARENA_THREADMARK */
598 563
599 rv->mark = p; 564 rv->mark = p;
600 rv->magic = MARK_MAGIC; 565 rv->magic = MARK_MAGIC;
601 566
602 #ifdef ARENA_DESTRUCTOR_LIST 567 #ifdef ARENA_DESTRUCTOR_LIST
603 rv->prev_destructor = arena->last_destructor; 568 rv->prev_destructor = arena->last_destructor;
604 #endif /* ARENA_DESTRUCTOR_LIST */ 569 #endif /* ARENA_DESTRUCTOR_LIST */
605 570
606 PR_Unlock(arena->lock); 571 PR_Unlock(arena->lock);
607 572
608 return rv; 573 return rv;
609 } 574 }
610 575
611 /* 576 /*
612 * nss_arena_unmark_release 577 * nss_arena_unmark_release
613 * 578 *
614 * This static routine implements the routines nssArena_Release 579 * This static routine implements the routines nssArena_Release
615 * ans nssArena_Unmark, which are almost identical. 580 * ans nssArena_Unmark, which are almost identical.
616 */ 581 */
617 582
618 static PRStatus 583 static PRStatus
619 nss_arena_unmark_release 584 nss_arena_unmark_release(NSSArena *arena, nssArenaMark *arenaMark,
620 ( 585 PRBool release)
621 NSSArena *arena,
622 nssArenaMark *arenaMark,
623 PRBool release
624 )
625 { 586 {
626 void *inner_mark; 587 void *inner_mark;
627 588
628 #ifdef NSSDEBUG 589 #ifdef NSSDEBUG
629 if( PR_SUCCESS != nssArena_verifyPointer(arena) ) { 590 if (PR_SUCCESS != nssArena_verifyPointer(arena)) {
630 return PR_FAILURE; 591 return PR_FAILURE;
631 } 592 }
632 #endif /* NSSDEBUG */ 593 #endif /* NSSDEBUG */
633 594
634 if( MARK_MAGIC != arenaMark->magic ) { 595 if (MARK_MAGIC != arenaMark->magic) {
635 nss_SetError(NSS_ERROR_INVALID_ARENA_MARK); 596 nss_SetError(NSS_ERROR_INVALID_ARENA_MARK);
636 return PR_FAILURE; 597 return PR_FAILURE;
637 } 598 }
638 599
639 if( (PRLock *)NULL == arena->lock ) { 600 if ((PRLock *)NULL == arena->lock) {
640 /* Just got destroyed */ 601 /* Just got destroyed */
641 nss_SetError(NSS_ERROR_INVALID_ARENA); 602 nss_SetError(NSS_ERROR_INVALID_ARENA);
642 return PR_FAILURE; 603 return PR_FAILURE;
643 } 604 }
644 PR_Lock(arena->lock); 605 PR_Lock(arena->lock);
645 606
646 #ifdef ARENA_THREADMARK 607 #ifdef ARENA_THREADMARK
647 if( (PRThread *)NULL != arena->marking_thread ) { 608 if ((PRThread *)NULL != arena->marking_thread) {
648 if( PR_GetCurrentThread() != arena->marking_thread ) { 609 if (PR_GetCurrentThread() != arena->marking_thread) {
649 PR_Unlock(arena->lock); 610 PR_Unlock(arena->lock);
650 nss_SetError(NSS_ERROR_ARENA_MARKED_BY_ANOTHER_THREAD); 611 nss_SetError(NSS_ERROR_ARENA_MARKED_BY_ANOTHER_THREAD);
651 return PR_FAILURE; 612 return PR_FAILURE;
613 }
652 } 614 }
653 }
654 #endif /* ARENA_THREADMARK */ 615 #endif /* ARENA_THREADMARK */
655 616
656 if( MARK_MAGIC != arenaMark->magic ) { 617 if (MARK_MAGIC != arenaMark->magic) {
657 /* Just got released */ 618 /* Just got released */
658 PR_Unlock(arena->lock); 619 PR_Unlock(arena->lock);
659 nss_SetError(NSS_ERROR_INVALID_ARENA_MARK); 620 nss_SetError(NSS_ERROR_INVALID_ARENA_MARK);
660 return PR_FAILURE; 621 return PR_FAILURE;
661 } 622 }
662 623
663 arenaMark->magic = 0; 624 arenaMark->magic = 0;
664 inner_mark = arenaMark->mark; 625 inner_mark = arenaMark->mark;
665 626
666 #ifdef ARENA_THREADMARK 627 #ifdef ARENA_THREADMARK
667 { 628 {
668 nssArenaMark **pMark = &arena->first_mark; 629 nssArenaMark **pMark = &arena->first_mark;
669 nssArenaMark *rest; 630 nssArenaMark *rest;
670 nssArenaMark *last = (nssArenaMark *)NULL; 631 nssArenaMark *last = (nssArenaMark *)NULL;
671 632
672 /* Find this mark */ 633 /* Find this mark */
673 while( *pMark != arenaMark ) { 634 while (*pMark != arenaMark) {
674 last = *pMark; 635 last = *pMark;
675 pMark = &(*pMark)->next; 636 pMark = &(*pMark)->next;
637 }
638
639 /* Remember the pointer, then zero it */
640 rest = (*pMark)->next;
641 *pMark = (nssArenaMark *)NULL;
642
643 arena->last_mark = last;
644
645 /* Invalidate any later marks being implicitly released */
646 for (; (nssArenaMark *)NULL != rest; rest = rest->next) {
647 rest->magic = 0;
648 }
649
650 /* If we just got rid of the first mark, clear the thread ID */
651 if ((nssArenaMark *)NULL == arena->first_mark) {
652 arena->marking_thread = (PRThread *)NULL;
653 }
654 }
655 #endif /* ARENA_THREADMARK */
656
657 if (release) {
658 #ifdef ARENA_DESTRUCTOR_LIST
659 if ((struct arena_destructor_node *)NULL !=
660 arenaMark->prev_destructor) {
661 arenaMark->prev_destructor->next =
662 (struct arena_destructor_node *)NULL;
663 }
664 arena->last_destructor = arenaMark->prev_destructor;
665
666 /* Note that the arena is locked at this time */
667 nss_arena_call_destructor_chain(arenaMark->next_destructor);
668 #endif /* ARENA_DESTRUCTOR_LIST */
669
670 PL_ARENA_RELEASE(&arena->pool, inner_mark);
671 /* No error return */
676 } 672 }
677 673
678 /* Remember the pointer, then zero it */ 674 PR_Unlock(arena->lock);
679 rest = (*pMark)->next; 675 return PR_SUCCESS;
680 *pMark = (nssArenaMark *)NULL;
681
682 arena->last_mark = last;
683
684 /* Invalidate any later marks being implicitly released */
685 for( ; (nssArenaMark *)NULL != rest; rest = rest->next ) {
686 rest->magic = 0;
687 }
688
689 /* If we just got rid of the first mark, clear the thread ID */
690 if( (nssArenaMark *)NULL == arena->first_mark ) {
691 arena->marking_thread = (PRThread *)NULL;
692 }
693 }
694 #endif /* ARENA_THREADMARK */
695
696 if( release ) {
697 #ifdef ARENA_DESTRUCTOR_LIST
698 if( (struct arena_destructor_node *)NULL != arenaMark->prev_destructor ) {
699 arenaMark->prev_destructor->next = (struct arena_destructor_node *)NULL;
700 }
701 arena->last_destructor = arenaMark->prev_destructor;
702
703 /* Note that the arena is locked at this time */
704 nss_arena_call_destructor_chain(arenaMark->next_destructor);
705 #endif /* ARENA_DESTRUCTOR_LIST */
706
707 PL_ARENA_RELEASE(&arena->pool, inner_mark);
708 /* No error return */
709 }
710
711 PR_Unlock(arena->lock);
712 return PR_SUCCESS;
713 } 676 }
714 677
715 /* 678 /*
716 * nssArena_Release 679 * nssArena_Release
717 * 680 *
718 * This routine invalidates and releases all memory allocated from 681 * This routine invalidates and releases all memory allocated from
719 * the specified arena after the point at which the specified mark 682 * the specified arena after the point at which the specified mark
720 * was obtained. This routine returns a PRStatus value; if successful, 683 * was obtained. This routine returns a PRStatus value; if successful,
721 * it will return PR_SUCCESS. If unsuccessful, it will set an error 684 * it will return PR_SUCCESS. If unsuccessful, it will set an error
722 * on the error stack and return PR_FAILURE. 685 * on the error stack and return PR_FAILURE.
723 * 686 *
724 * The error may be one of the following values: 687 * The error may be one of the following values:
725 * NSS_ERROR_INVALID_ARENA 688 * NSS_ERROR_INVALID_ARENA
726 * NSS_ERROR_INVALID_ARENA_MARK 689 * NSS_ERROR_INVALID_ARENA_MARK
727 * NSS_ERROR_ARENA_MARKED_BY_ANOTHER_THREAD 690 * NSS_ERROR_ARENA_MARKED_BY_ANOTHER_THREAD
728 * 691 *
729 * Return value: 692 * Return value:
730 * PR_SUCCESS 693 * PR_SUCCESS
731 * PR_FAILURE 694 * PR_FAILURE
732 */ 695 */
733 696
734 NSS_IMPLEMENT PRStatus 697 NSS_IMPLEMENT PRStatus
735 nssArena_Release 698 nssArena_Release(NSSArena *arena, nssArenaMark *arenaMark)
736 (
737 NSSArena *arena,
738 nssArenaMark *arenaMark
739 )
740 { 699 {
741 return nss_arena_unmark_release(arena, arenaMark, PR_TRUE); 700 return nss_arena_unmark_release(arena, arenaMark, PR_TRUE);
742 } 701 }
743 702
744 /* 703 /*
745 * nssArena_Unmark 704 * nssArena_Unmark
746 * 705 *
747 * This routine "commits" the indicated mark and any marks after 706 * This routine "commits" the indicated mark and any marks after
748 * it, making them unreleasable. Note that any earlier marks can 707 * it, making them unreleasable. Note that any earlier marks can
749 * still be released, and such a release will invalidate these 708 * still be released, and such a release will invalidate these
750 * later unmarked regions. If an arena is to be safely shared by 709 * later unmarked regions. If an arena is to be safely shared by
751 * more than one thread, all marks must be either released or 710 * more than one thread, all marks must be either released or
752 * unmarked. This routine returns a PRStatus value; if successful, 711 * unmarked. This routine returns a PRStatus value; if successful,
753 * it will return PR_SUCCESS. If unsuccessful, it will set an error 712 * it will return PR_SUCCESS. If unsuccessful, it will set an error
754 * on the error stack and return PR_FAILURE. 713 * on the error stack and return PR_FAILURE.
755 * 714 *
756 * The error may be one of the following values: 715 * The error may be one of the following values:
757 * NSS_ERROR_INVALID_ARENA 716 * NSS_ERROR_INVALID_ARENA
758 * NSS_ERROR_INVALID_ARENA_MARK 717 * NSS_ERROR_INVALID_ARENA_MARK
759 * NSS_ERROR_ARENA_MARKED_BY_ANOTHER_THREAD 718 * NSS_ERROR_ARENA_MARKED_BY_ANOTHER_THREAD
760 * 719 *
761 * Return value: 720 * Return value:
762 * PR_SUCCESS 721 * PR_SUCCESS
763 * PR_FAILURE 722 * PR_FAILURE
764 */ 723 */
765 724
766 NSS_IMPLEMENT PRStatus 725 NSS_IMPLEMENT PRStatus
767 nssArena_Unmark 726 nssArena_Unmark(NSSArena *arena, nssArenaMark *arenaMark)
768 (
769 NSSArena *arena,
770 nssArenaMark *arenaMark
771 )
772 { 727 {
773 return nss_arena_unmark_release(arena, arenaMark, PR_FALSE); 728 return nss_arena_unmark_release(arena, arenaMark, PR_FALSE);
774 } 729 }
775 730
776 /* 731 /*
777 * We prefix this header to all allocated blocks. It is a multiple 732 * We prefix this header to all allocated blocks. It is a multiple
778 * of the alignment size. Note that this usage of a header may make 733 * of the alignment size. Note that this usage of a header may make
779 * purify spew bogus warnings about "potentially leaked blocks" of 734 * purify spew bogus warnings about "potentially leaked blocks" of
780 * memory; if that gets too annoying we can add in a pointer to the 735 * memory; if that gets too annoying we can add in a pointer to the
781 * header in the header itself. There's not a lot of safety here; 736 * header in the header itself. There's not a lot of safety here;
782 * maybe we should add a magic value? 737 * maybe we should add a magic value?
783 */ 738 */
784 struct pointer_header { 739 struct pointer_header {
785 NSSArena *arena; 740 NSSArena *arena;
786 PRUint32 size; 741 PRUint32 size;
787 }; 742 };
788 743
789 static void * 744 static void *
790 nss_zalloc_arena_locked 745 nss_zalloc_arena_locked(NSSArena *arena, PRUint32 size)
791 (
792 NSSArena *arena,
793 PRUint32 size
794 )
795 { 746 {
796 void *p; 747 void *p;
797 void *rv; 748 void *rv;
798 struct pointer_header *h; 749 struct pointer_header *h;
799 PRUint32 my_size = size + sizeof(struct pointer_header); 750 PRUint32 my_size = size + sizeof(struct pointer_header);
800 PL_ARENA_ALLOCATE(p, &arena->pool, my_size); 751 PL_ARENA_ALLOCATE(p, &arena->pool, my_size);
801 if( (void *)NULL == p ) { 752 if ((void *)NULL == p) {
802 nss_SetError(NSS_ERROR_NO_MEMORY); 753 nss_SetError(NSS_ERROR_NO_MEMORY);
803 return (void *)NULL; 754 return (void *)NULL;
804 } 755 }
805 /* 756 /*
806 * Do this before we unlock. This way if the user is using 757 * Do this before we unlock. This way if the user is using
807 * an arena in one thread while destroying it in another, he'll 758 * an arena in one thread while destroying it in another, he'll
808 * fault/FMR in his code, not ours. 759 * fault/FMR in his code, not ours.
809 */ 760 */
810 h = (struct pointer_header *)p; 761 h = (struct pointer_header *)p;
811 h->arena = arena; 762 h->arena = arena;
812 h->size = size; 763 h->size = size;
813 rv = (void *)((char *)h + sizeof(struct pointer_header)); 764 rv = (void *)((char *)h + sizeof(struct pointer_header));
814 (void)nsslibc_memset(rv, 0, size); 765 (void)nsslibc_memset(rv, 0, size);
815 return rv; 766 return rv;
816 } 767 }
817 768
818 /* 769 /*
819 * NSS_ZAlloc 770 * NSS_ZAlloc
820 * 771 *
821 * This routine allocates and zeroes a section of memory of the 772 * This routine allocates and zeroes a section of memory of the
822 * size, and returns to the caller a pointer to that memory. If 773 * size, and returns to the caller a pointer to that memory. If
823 * the optional arena argument is non-null, the memory will be 774 * the optional arena argument is non-null, the memory will be
824 * obtained from that arena; otherwise, the memory will be obtained 775 * obtained from that arena; otherwise, the memory will be obtained
825 * from the heap. This routine may return NULL upon error, in 776 * from the heap. This routine may return NULL upon error, in
826 * which case it will have set an error upon the error stack. The 777 * which case it will have set an error upon the error stack. The
827 * value specified for size may be zero; in which case a valid 778 * value specified for size may be zero; in which case a valid
828 * zero-length block of memory will be allocated. This block may 779 * zero-length block of memory will be allocated. This block may
829 * be expanded by calling NSS_ZRealloc. 780 * be expanded by calling NSS_ZRealloc.
830 * 781 *
831 * The error may be one of the following values: 782 * The error may be one of the following values:
832 * NSS_ERROR_INVALID_ARENA 783 * NSS_ERROR_INVALID_ARENA
833 * NSS_ERROR_NO_MEMORY 784 * NSS_ERROR_NO_MEMORY
834 * NSS_ERROR_ARENA_MARKED_BY_ANOTHER_THREAD 785 * NSS_ERROR_ARENA_MARKED_BY_ANOTHER_THREAD
835 * 786 *
836 * Return value: 787 * Return value:
837 * NULL upon error 788 * NULL upon error
838 * A pointer to the new segment of zeroed memory 789 * A pointer to the new segment of zeroed memory
839 */ 790 */
840 791
841 NSS_IMPLEMENT void * 792 NSS_IMPLEMENT void *
842 NSS_ZAlloc 793 NSS_ZAlloc(NSSArena *arenaOpt, PRUint32 size)
843 (
844 NSSArena *arenaOpt,
845 PRUint32 size
846 )
847 { 794 {
848 return nss_ZAlloc(arenaOpt, size); 795 return nss_ZAlloc(arenaOpt, size);
849 } 796 }
850 797
851 /* 798 /*
852 * nss_ZAlloc 799 * nss_ZAlloc
853 * 800 *
854 * This routine allocates and zeroes a section of memory of the 801 * This routine allocates and zeroes a section of memory of the
855 * size, and returns to the caller a pointer to that memory. If 802 * size, and returns to the caller a pointer to that memory. If
856 * the optional arena argument is non-null, the memory will be 803 * the optional arena argument is non-null, the memory will be
857 * obtained from that arena; otherwise, the memory will be obtained 804 * obtained from that arena; otherwise, the memory will be obtained
858 * from the heap. This routine may return NULL upon error, in 805 * from the heap. This routine may return NULL upon error, in
859 * which case it will have set an error upon the error stack. The 806 * which case it will have set an error upon the error stack. The
860 * value specified for size may be zero; in which case a valid 807 * value specified for size may be zero; in which case a valid
861 * zero-length block of memory will be allocated. This block may 808 * zero-length block of memory will be allocated. This block may
862 * be expanded by calling nss_ZRealloc. 809 * be expanded by calling nss_ZRealloc.
863 * 810 *
864 * The error may be one of the following values: 811 * The error may be one of the following values:
865 * NSS_ERROR_INVALID_ARENA 812 * NSS_ERROR_INVALID_ARENA
866 * NSS_ERROR_NO_MEMORY 813 * NSS_ERROR_NO_MEMORY
867 * NSS_ERROR_ARENA_MARKED_BY_ANOTHER_THREAD 814 * NSS_ERROR_ARENA_MARKED_BY_ANOTHER_THREAD
868 * 815 *
869 * Return value: 816 * Return value:
870 * NULL upon error 817 * NULL upon error
871 * A pointer to the new segment of zeroed memory 818 * A pointer to the new segment of zeroed memory
872 */ 819 */
873 820
874 NSS_IMPLEMENT void * 821 NSS_IMPLEMENT void *
875 nss_ZAlloc 822 nss_ZAlloc(NSSArena *arenaOpt, PRUint32 size)
876 (
877 NSSArena *arenaOpt,
878 PRUint32 size
879 )
880 { 823 {
881 struct pointer_header *h; 824 struct pointer_header *h;
882 PRUint32 my_size = size + sizeof(struct pointer_header); 825 PRUint32 my_size = size + sizeof(struct pointer_header);
883 826
884 if( my_size < sizeof(struct pointer_header) ) { 827 if (my_size < sizeof(struct pointer_header)) {
885 /* Wrapped */ 828 /* Wrapped */
886 nss_SetError(NSS_ERROR_NO_MEMORY); 829 nss_SetError(NSS_ERROR_NO_MEMORY);
887 return (void *)NULL; 830 return (void *)NULL;
888 }
889
890 if( (NSSArena *)NULL == arenaOpt ) {
891 /* Heap allocation, no locking required. */
892 h = (struct pointer_header *)PR_Calloc(1, my_size);
893 if( (struct pointer_header *)NULL == h ) {
894 nss_SetError(NSS_ERROR_NO_MEMORY);
895 return (void *)NULL;
896 } 831 }
897 832
898 h->arena = (NSSArena *)NULL; 833 if ((NSSArena *)NULL == arenaOpt) {
899 h->size = size; 834 /* Heap allocation, no locking required. */
900 /* We used calloc: it's already zeroed */ 835 h = (struct pointer_header *)PR_Calloc(1, my_size);
836 if ((struct pointer_header *)NULL == h) {
837 nss_SetError(NSS_ERROR_NO_MEMORY);
838 return (void *)NULL;
839 }
901 840
902 return (void *)((char *)h + sizeof(struct pointer_header)); 841 h->arena = (NSSArena *)NULL;
903 } else { 842 h->size = size;
904 void *rv; 843 /* We used calloc: it's already zeroed */
905 /* Arena allocation */ 844
845 return (void *)((char *)h + sizeof(struct pointer_header));
846 } else {
847 void *rv;
848 /* Arena allocation */
906 #ifdef NSSDEBUG 849 #ifdef NSSDEBUG
907 if( PR_SUCCESS != nssArena_verifyPointer(arenaOpt) ) { 850 if (PR_SUCCESS != nssArena_verifyPointer(arenaOpt)) {
908 return (void *)NULL; 851 return (void *)NULL;
909 } 852 }
910 #endif /* NSSDEBUG */ 853 #endif /* NSSDEBUG */
911 854
912 if( (PRLock *)NULL == arenaOpt->lock ) { 855 if ((PRLock *)NULL == arenaOpt->lock) {
913 /* Just got destroyed */ 856 /* Just got destroyed */
914 nss_SetError(NSS_ERROR_INVALID_ARENA); 857 nss_SetError(NSS_ERROR_INVALID_ARENA);
915 return (void *)NULL; 858 return (void *)NULL;
916 } 859 }
917 PR_Lock(arenaOpt->lock); 860 PR_Lock(arenaOpt->lock);
918 861
919 #ifdef ARENA_THREADMARK 862 #ifdef ARENA_THREADMARK
920 if( (PRThread *)NULL != arenaOpt->marking_thread ) { 863 if ((PRThread *)NULL != arenaOpt->marking_thread) {
921 if( PR_GetCurrentThread() != arenaOpt->marking_thread ) { 864 if (PR_GetCurrentThread() != arenaOpt->marking_thread) {
922 nss_SetError(NSS_ERROR_ARENA_MARKED_BY_ANOTHER_THREAD); 865 nss_SetError(NSS_ERROR_ARENA_MARKED_BY_ANOTHER_THREAD);
923 PR_Unlock(arenaOpt->lock); 866 PR_Unlock(arenaOpt->lock);
924 return (void *)NULL; 867 return (void *)NULL;
925 } 868 }
926 } 869 }
927 #endif /* ARENA_THREADMARK */ 870 #endif /* ARENA_THREADMARK */
928 871
929 rv = nss_zalloc_arena_locked(arenaOpt, size); 872 rv = nss_zalloc_arena_locked(arenaOpt, size);
930 873
931 PR_Unlock(arenaOpt->lock); 874 PR_Unlock(arenaOpt->lock);
932 return rv; 875 return rv;
933 } 876 }
934 /*NOTREACHED*/ 877 /*NOTREACHED*/
935 } 878 }
936 879
937 /* 880 /*
938 * NSS_ZFreeIf 881 * NSS_ZFreeIf
939 * 882 *
940 * If the specified pointer is non-null, then the region of memory 883 * If the specified pointer is non-null, then the region of memory
941 * to which it points -- which must have been allocated with 884 * to which it points -- which must have been allocated with
942 * NSS_ZAlloc -- will be zeroed and released. This routine 885 * NSS_ZAlloc -- will be zeroed and released. This routine
943 * returns a PRStatus value; if successful, it will return PR_SUCCESS. 886 * returns a PRStatus value; if successful, it will return PR_SUCCESS.
944 * If unsuccessful, it will set an error on the error stack and return 887 * If unsuccessful, it will set an error on the error stack and return
945 * PR_FAILURE. 888 * PR_FAILURE.
946 * 889 *
947 * The error may be one of the following values: 890 * The error may be one of the following values:
948 * NSS_ERROR_INVALID_POINTER 891 * NSS_ERROR_INVALID_POINTER
949 * 892 *
950 * Return value: 893 * Return value:
951 * PR_SUCCESS 894 * PR_SUCCESS
952 * PR_FAILURE 895 * PR_FAILURE
953 */ 896 */
954 NSS_IMPLEMENT PRStatus 897 NSS_IMPLEMENT PRStatus
955 NSS_ZFreeIf 898 NSS_ZFreeIf(void *pointer)
956 (
957 void *pointer
958 )
959 { 899 {
960 return nss_ZFreeIf(pointer); 900 return nss_ZFreeIf(pointer);
961 } 901 }
962 902
963 /* 903 /*
964 * nss_ZFreeIf 904 * nss_ZFreeIf
965 * 905 *
966 * If the specified pointer is non-null, then the region of memory 906 * If the specified pointer is non-null, then the region of memory
967 * to which it points -- which must have been allocated with 907 * to which it points -- which must have been allocated with
968 * nss_ZAlloc -- will be zeroed and released. This routine 908 * nss_ZAlloc -- will be zeroed and released. This routine
969 * returns a PRStatus value; if successful, it will return PR_SUCCESS. 909 * returns a PRStatus value; if successful, it will return PR_SUCCESS.
970 * If unsuccessful, it will set an error on the error stack and return 910 * If unsuccessful, it will set an error on the error stack and return
971 * PR_FAILURE. 911 * PR_FAILURE.
972 * 912 *
973 * The error may be one of the following values: 913 * The error may be one of the following values:
974 * NSS_ERROR_INVALID_POINTER 914 * NSS_ERROR_INVALID_POINTER
975 * 915 *
976 * Return value: 916 * Return value:
977 * PR_SUCCESS 917 * PR_SUCCESS
978 * PR_FAILURE 918 * PR_FAILURE
979 */ 919 */
980 920
981 NSS_IMPLEMENT PRStatus 921 NSS_IMPLEMENT PRStatus
982 nss_ZFreeIf 922 nss_ZFreeIf(void *pointer)
983 (
984 void *pointer
985 )
986 { 923 {
987 struct pointer_header *h; 924 struct pointer_header *h;
988 925
989 if( (void *)NULL == pointer ) { 926 if ((void *)NULL == pointer) {
990 return PR_SUCCESS; 927 return PR_SUCCESS;
991 } 928 }
992 929
993 h = (struct pointer_header *)((char *)pointer 930 h = (struct pointer_header *)((char *)pointer -
994 - sizeof(struct pointer_header)); 931 sizeof(struct pointer_header));
995 932
996 /* Check any magic here */ 933 /* Check any magic here */
997 934
998 if( (NSSArena *)NULL == h->arena ) { 935 if ((NSSArena *)NULL == h->arena) {
999 /* Heap */ 936 /* Heap */
1000 (void)nsslibc_memset(pointer, 0, h->size); 937 (void)nsslibc_memset(pointer, 0, h->size);
1001 PR_Free(h); 938 PR_Free(h);
1002 return PR_SUCCESS; 939 return PR_SUCCESS;
1003 } else { 940 } else {
1004 /* Arena */ 941 /* Arena */
1005 #ifdef NSSDEBUG 942 #ifdef NSSDEBUG
1006 if( PR_SUCCESS != nssArena_verifyPointer(h->arena) ) { 943 if (PR_SUCCESS != nssArena_verifyPointer(h->arena)) {
1007 return PR_FAILURE; 944 return PR_FAILURE;
1008 } 945 }
1009 #endif /* NSSDEBUG */ 946 #endif /* NSSDEBUG */
1010 947
1011 if( (PRLock *)NULL == h->arena->lock ) { 948 if ((PRLock *)NULL == h->arena->lock) {
1012 /* Just got destroyed.. so this pointer is invalid */ 949 /* Just got destroyed.. so this pointer is invalid */
1013 nss_SetError(NSS_ERROR_INVALID_POINTER); 950 nss_SetError(NSS_ERROR_INVALID_POINTER);
1014 return PR_FAILURE; 951 return PR_FAILURE;
952 }
953 PR_Lock(h->arena->lock);
954
955 (void)nsslibc_memset(pointer, 0, h->size);
956
957 /* No way to "free" it within an NSPR arena. */
958
959 PR_Unlock(h->arena->lock);
960 return PR_SUCCESS;
1015 } 961 }
1016 PR_Lock(h->arena->lock); 962 /*NOTREACHED*/
1017
1018 (void)nsslibc_memset(pointer, 0, h->size);
1019
1020 /* No way to "free" it within an NSPR arena. */
1021
1022 PR_Unlock(h->arena->lock);
1023 return PR_SUCCESS;
1024 }
1025 /*NOTREACHED*/
1026 } 963 }
1027 964
1028 /* 965 /*
1029 * NSS_ZRealloc 966 * NSS_ZRealloc
1030 * 967 *
1031 * This routine reallocates a block of memory obtained by calling 968 * This routine reallocates a block of memory obtained by calling
1032 * nss_ZAlloc or nss_ZRealloc. The portion of memory 969 * nss_ZAlloc or nss_ZRealloc. The portion of memory
1033 * between the new and old sizes -- which is either being newly 970 * between the new and old sizes -- which is either being newly
1034 * obtained or released -- is in either case zeroed. This routine 971 * obtained or released -- is in either case zeroed. This routine
1035 * may return NULL upon failure, in which case it will have placed 972 * may return NULL upon failure, in which case it will have placed
1036 * an error on the error stack. 973 * an error on the error stack.
1037 * 974 *
1038 * The error may be one of the following values: 975 * The error may be one of the following values:
1039 * NSS_ERROR_INVALID_POINTER 976 * NSS_ERROR_INVALID_POINTER
1040 * NSS_ERROR_NO_MEMORY 977 * NSS_ERROR_NO_MEMORY
1041 * NSS_ERROR_ARENA_MARKED_BY_ANOTHER_THREAD 978 * NSS_ERROR_ARENA_MARKED_BY_ANOTHER_THREAD
1042 * 979 *
1043 * Return value: 980 * Return value:
1044 * NULL upon error 981 * NULL upon error
1045 * A pointer to the replacement segment of memory 982 * A pointer to the replacement segment of memory
1046 */ 983 */
1047 984
1048 NSS_EXTERN void * 985 NSS_EXTERN void *
1049 NSS_ZRealloc 986 NSS_ZRealloc(void *pointer, PRUint32 newSize)
1050 (
1051 void *pointer,
1052 PRUint32 newSize
1053 )
1054 { 987 {
1055 return nss_ZRealloc(pointer, newSize); 988 return nss_ZRealloc(pointer, newSize);
1056 } 989 }
1057 990
1058 /* 991 /*
1059 * nss_ZRealloc 992 * nss_ZRealloc
1060 * 993 *
1061 * This routine reallocates a block of memory obtained by calling 994 * This routine reallocates a block of memory obtained by calling
1062 * nss_ZAlloc or nss_ZRealloc. The portion of memory 995 * nss_ZAlloc or nss_ZRealloc. The portion of memory
1063 * between the new and old sizes -- which is either being newly 996 * between the new and old sizes -- which is either being newly
1064 * obtained or released -- is in either case zeroed. This routine 997 * obtained or released -- is in either case zeroed. This routine
1065 * may return NULL upon failure, in which case it will have placed 998 * may return NULL upon failure, in which case it will have placed
1066 * an error on the error stack. 999 * an error on the error stack.
1067 * 1000 *
1068 * The error may be one of the following values: 1001 * The error may be one of the following values:
1069 * NSS_ERROR_INVALID_POINTER 1002 * NSS_ERROR_INVALID_POINTER
1070 * NSS_ERROR_NO_MEMORY 1003 * NSS_ERROR_NO_MEMORY
1071 * NSS_ERROR_ARENA_MARKED_BY_ANOTHER_THREAD 1004 * NSS_ERROR_ARENA_MARKED_BY_ANOTHER_THREAD
1072 * 1005 *
1073 * Return value: 1006 * Return value:
1074 * NULL upon error 1007 * NULL upon error
1075 * A pointer to the replacement segment of memory 1008 * A pointer to the replacement segment of memory
1076 */ 1009 */
1077 1010
1078 NSS_EXTERN void * 1011 NSS_EXTERN void *
1079 nss_ZRealloc 1012 nss_ZRealloc(void *pointer, PRUint32 newSize)
1080 (
1081 void *pointer,
1082 PRUint32 newSize
1083 )
1084 { 1013 {
1085 NSSArena *arena; 1014 NSSArena *arena;
1086 struct pointer_header *h, *new_h; 1015 struct pointer_header *h, *new_h;
1087 PRUint32 my_newSize = newSize + sizeof(struct pointer_header); 1016 PRUint32 my_newSize = newSize + sizeof(struct pointer_header);
1088 void *rv; 1017 void *rv;
1089 1018
1090 if( my_newSize < sizeof(struct pointer_header) ) { 1019 if (my_newSize < sizeof(struct pointer_header)) {
1091 /* Wrapped */ 1020 /* Wrapped */
1092 nss_SetError(NSS_ERROR_NO_MEMORY); 1021 nss_SetError(NSS_ERROR_NO_MEMORY);
1093 return (void *)NULL; 1022 return (void *)NULL;
1094 }
1095
1096 if( (void *)NULL == pointer ) {
1097 nss_SetError(NSS_ERROR_INVALID_POINTER);
1098 return (void *)NULL;
1099 }
1100
1101 h = (struct pointer_header *)((char *)pointer
1102 - sizeof(struct pointer_header));
1103
1104 /* Check any magic here */
1105
1106 if( newSize == h->size ) {
1107 /* saves thrashing */
1108 return pointer;
1109 }
1110
1111 arena = h->arena;
1112 if (!arena) {
1113 /* Heap */
1114 new_h = (struct pointer_header *)PR_Calloc(1, my_newSize);
1115 if( (struct pointer_header *)NULL == new_h ) {
1116 nss_SetError(NSS_ERROR_NO_MEMORY);
1117 return (void *)NULL;
1118 } 1023 }
1119 1024
1120 new_h->arena = (NSSArena *)NULL; 1025 if ((void *)NULL == pointer) {
1121 new_h->size = newSize; 1026 nss_SetError(NSS_ERROR_INVALID_POINTER);
1122 rv = (void *)((char *)new_h + sizeof(struct pointer_header)); 1027 return (void *)NULL;
1123
1124 if( newSize > h->size ) {
1125 (void)nsslibc_memcpy(rv, pointer, h->size);
1126 (void)nsslibc_memset(&((char *)rv)[ h->size ],
1127 0, (newSize - h->size));
1128 } else {
1129 (void)nsslibc_memcpy(rv, pointer, newSize);
1130 } 1028 }
1131 1029
1132 (void)nsslibc_memset(pointer, 0, h->size); 1030 h = (struct pointer_header *)((char *)pointer -
1133 h->size = 0; 1031 sizeof(struct pointer_header));
1134 PR_Free(h);
1135 1032
1136 return rv; 1033 /* Check any magic here */
1137 } else { 1034
1138 void *p; 1035 if (newSize == h->size) {
1139 /* Arena */ 1036 /* saves thrashing */
1037 return pointer;
1038 }
1039
1040 arena = h->arena;
1041 if (!arena) {
1042 /* Heap */
1043 new_h = (struct pointer_header *)PR_Calloc(1, my_newSize);
1044 if ((struct pointer_header *)NULL == new_h) {
1045 nss_SetError(NSS_ERROR_NO_MEMORY);
1046 return (void *)NULL;
1047 }
1048
1049 new_h->arena = (NSSArena *)NULL;
1050 new_h->size = newSize;
1051 rv = (void *)((char *)new_h + sizeof(struct pointer_header));
1052
1053 if (newSize > h->size) {
1054 (void)nsslibc_memcpy(rv, pointer, h->size);
1055 (void)nsslibc_memset(&((char *)rv)[h->size], 0,
1056 (newSize - h->size));
1057 } else {
1058 (void)nsslibc_memcpy(rv, pointer, newSize);
1059 }
1060
1061 (void)nsslibc_memset(pointer, 0, h->size);
1062 h->size = 0;
1063 PR_Free(h);
1064
1065 return rv;
1066 } else {
1067 void *p;
1068 /* Arena */
1140 #ifdef NSSDEBUG 1069 #ifdef NSSDEBUG
1141 if (PR_SUCCESS != nssArena_verifyPointer(arena)) { 1070 if (PR_SUCCESS != nssArena_verifyPointer(arena)) {
1142 return (void *)NULL; 1071 return (void *)NULL;
1143 } 1072 }
1144 #endif /* NSSDEBUG */ 1073 #endif /* NSSDEBUG */
1145 1074
1146 if (!arena->lock) { 1075 if (!arena->lock) {
1147 /* Just got destroyed.. so this pointer is invalid */ 1076 /* Just got destroyed.. so this pointer is invalid */
1148 nss_SetError(NSS_ERROR_INVALID_POINTER); 1077 nss_SetError(NSS_ERROR_INVALID_POINTER);
1149 return (void *)NULL; 1078 return (void *)NULL;
1150 } 1079 }
1151 PR_Lock(arena->lock); 1080 PR_Lock(arena->lock);
1152 1081
1153 #ifdef ARENA_THREADMARK 1082 #ifdef ARENA_THREADMARK
1154 if (arena->marking_thread) { 1083 if (arena->marking_thread) {
1155 if (PR_GetCurrentThread() != arena->marking_thread) { 1084 if (PR_GetCurrentThread() != arena->marking_thread) {
1156 PR_Unlock(arena->lock); 1085 PR_Unlock(arena->lock);
1157 nss_SetError(NSS_ERROR_ARENA_MARKED_BY_ANOTHER_THREAD); 1086 nss_SetError(NSS_ERROR_ARENA_MARKED_BY_ANOTHER_THREAD);
1158 return (void *)NULL; 1087 return (void *)NULL;
1159 } 1088 }
1160 } 1089 }
1161 #endif /* ARENA_THREADMARK */ 1090 #endif /* ARENA_THREADMARK */
1162 1091
1163 if( newSize < h->size ) { 1092 if (newSize < h->size) {
1164 /* 1093 /*
1165 * We have no general way of returning memory to the arena 1094 * We have no general way of returning memory to the arena
1166 * (mark/release doesn't work because things may have been 1095 * (mark/release doesn't work because things may have been
1167 * allocated after this object), so the memory is gone 1096 * allocated after this object), so the memory is gone
1168 * anyway. We might as well just return the same pointer to 1097 * anyway. We might as well just return the same pointer to
1169 * the user, saying "yeah, uh-hunh, you can only use less of 1098 * the user, saying "yeah, uh-hunh, you can only use less of
1170 * it now." We'll zero the leftover part, of course. And 1099 * it now." We'll zero the leftover part, of course. And
1171 * in fact we might as well *not* adjust h->size-- this way, 1100 * in fact we might as well *not* adjust h->size-- this way,
1172 * if the user reallocs back up to something not greater than 1101 * if the user reallocs back up to something not greater than
1173 * the original size, then voila, there's the memory! This 1102 * the original size, then voila, there's the memory! This
1174 * way a thrash big/small/big/small doesn't burn up the arena. 1103 * way a thrash big/small/big/small doesn't burn up the arena.
1175 */ 1104 */
1176 char *extra = &((char *)pointer)[ newSize ]; 1105 char *extra = &((char *)pointer)[newSize];
1177 (void)nsslibc_memset(extra, 0, (h->size - newSize)); 1106 (void)nsslibc_memset(extra, 0, (h->size - newSize));
1178 PR_Unlock(arena->lock); 1107 PR_Unlock(arena->lock);
1179 return pointer; 1108 return pointer;
1109 }
1110
1111 PL_ARENA_ALLOCATE(p, &arena->pool, my_newSize);
1112 if ((void *)NULL == p) {
1113 PR_Unlock(arena->lock);
1114 nss_SetError(NSS_ERROR_NO_MEMORY);
1115 return (void *)NULL;
1116 }
1117
1118 new_h = (struct pointer_header *)p;
1119 new_h->arena = arena;
1120 new_h->size = newSize;
1121 rv = (void *)((char *)new_h + sizeof(struct pointer_header));
1122 if (rv != pointer) {
1123 (void)nsslibc_memcpy(rv, pointer, h->size);
1124 (void)nsslibc_memset(pointer, 0, h->size);
1125 }
1126 (void)nsslibc_memset(&((char *)rv)[h->size], 0, (newSize - h->size));
1127 h->arena = (NSSArena *)NULL;
1128 h->size = 0;
1129 PR_Unlock(arena->lock);
1130 return rv;
1180 } 1131 }
1181 1132 /*NOTREACHED*/
1182 PL_ARENA_ALLOCATE(p, &arena->pool, my_newSize);
1183 if( (void *)NULL == p ) {
1184 PR_Unlock(arena->lock);
1185 nss_SetError(NSS_ERROR_NO_MEMORY);
1186 return (void *)NULL;
1187 }
1188
1189 new_h = (struct pointer_header *)p;
1190 new_h->arena = arena;
1191 new_h->size = newSize;
1192 rv = (void *)((char *)new_h + sizeof(struct pointer_header));
1193 if (rv != pointer) {
1194 » (void)nsslibc_memcpy(rv, pointer, h->size);
1195 » (void)nsslibc_memset(pointer, 0, h->size);
1196 }
1197 (void)nsslibc_memset(&((char *)rv)[ h->size ], 0, (newSize - h->size));
1198 h->arena = (NSSArena *)NULL;
1199 h->size = 0;
1200 PR_Unlock(arena->lock);
1201 return rv;
1202 }
1203 /*NOTREACHED*/
1204 } 1133 }
1205 1134
1206 PRStatus 1135 PRStatus
1207 nssArena_Shutdown(void) 1136 nssArena_Shutdown(void)
1208 { 1137 {
1209 PRStatus rv = PR_SUCCESS; 1138 PRStatus rv = PR_SUCCESS;
1210 #ifdef DEBUG 1139 #ifdef DEBUG
1211 rv = nssPointerTracker_finalize(&arena_pointer_tracker); 1140 rv = nssPointerTracker_finalize(&arena_pointer_tracker);
1212 #endif 1141 #endif
1213 return rv; 1142 return rv;
1214 } 1143 }
OLDNEW
« no previous file with comments | « nss/exports_win.def ('k') | nss/lib/base/base.h » ('j') | nss/lib/util/secoid.c » ('J')

Powered by Google App Engine
This is Rietveld 408576698