From d6fa83b92119ea3b278e6eb7101e07968f19293b Mon Sep 17 00:00:00 2001 From: "nelson%bolyard.com" Date: Sat, 23 Feb 2008 05:29:39 +0000 Subject: [PATCH] Bug 370536: Memory leaks in pointer tracker code in DEBUG builds. r=rrelyea git-svn-id: svn://10.0.0.236/trunk@246341 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/security/nss/lib/base/arena.c | 11 ++- mozilla/security/nss/lib/base/base.h | 9 ++- mozilla/security/nss/lib/base/tracker.c | 103 +----------------------- mozilla/security/nss/lib/nss/nssinit.c | 3 +- 4 files changed, 22 insertions(+), 104 deletions(-) diff --git a/mozilla/security/nss/lib/base/arena.c b/mozilla/security/nss/lib/base/arena.c index 425943a788e..76132fe66c0 100644 --- a/mozilla/security/nss/lib/base/arena.c +++ b/mozilla/security/nss/lib/base/arena.c @@ -35,7 +35,7 @@ * ***** END LICENSE BLOCK ***** */ #ifdef DEBUG -static const char CVS_ID[] = "@(#) $RCSfile: arena.c,v $ $Revision: 1.9 $ $Date: 2006-07-17 21:51:32 $"; +static const char CVS_ID[] = "@(#) $RCSfile: arena.c,v $ $Revision: 1.10 $ $Date: 2008-02-23 05:29:23 $"; #endif /* DEBUG */ /* @@ -1143,3 +1143,12 @@ nss_ZRealloc } /*NOTREACHED*/ } + +PRStatus +nssArena_Shutdown(void) +{ + PRStatus rv; + + rv = nssPointerTracker_finalize(&arena_pointer_tracker); + return rv; +} diff --git a/mozilla/security/nss/lib/base/base.h b/mozilla/security/nss/lib/base/base.h index a565b2c20ae..a18d6ef14e0 100644 --- a/mozilla/security/nss/lib/base/base.h +++ b/mozilla/security/nss/lib/base/base.h @@ -38,7 +38,7 @@ #define BASE_H #ifdef DEBUG -static const char BASE_CVS_ID[] = "@(#) $RCSfile: base.h,v $ $Revision: 1.18 $ $Date: 2005-12-19 17:53:28 $"; +static const char BASE_CVS_ID[] = "@(#) $RCSfile: base.h,v $ $Revision: 1.19 $ $Date: 2008-02-23 05:29:23 $"; #endif /* DEBUG */ /* @@ -519,6 +519,13 @@ extern const NSSError NSS_ERROR_INVALID_ARENA; #define nssArena_VERIFYPOINTER(p) (((NSSArena *)NULL == (p))?PR_FAILURE:PR_SUCCESS) #endif /* DEBUG */ +/* + * Private function to be called by NSS_Shutdown to cleanup nssArena + * bookkeeping. + */ +extern PRStatus +nssArena_Shutdown(void); + /* * nssArenaHashAllocOps * diff --git a/mozilla/security/nss/lib/base/tracker.c b/mozilla/security/nss/lib/base/tracker.c index 3db482fb232..0e19d4aeaf8 100644 --- a/mozilla/security/nss/lib/base/tracker.c +++ b/mozilla/security/nss/lib/base/tracker.c @@ -35,7 +35,7 @@ * ***** END LICENSE BLOCK ***** */ #ifdef DEBUG -static const char CVS_ID[] = "@(#) $RCSfile: tracker.c,v $ $Revision: 1.6 $ $Date: 2005-01-20 02:25:45 $"; +static const char CVS_ID[] = "@(#) $RCSfile: tracker.c,v $ $Revision: 1.7 $ $Date: 2008-02-23 05:29:24 $"; #endif /* DEBUG */ /* @@ -51,105 +51,6 @@ static const char CVS_ID[] = "@(#) $RCSfile: tracker.c,v $ $Revision: 1.6 $ $Dat #endif /* BASE_H */ #ifdef DEBUG - -/* - * call_once - * - * Unfortunately, NSPR's PR_CallOnce function doesn't accept a closure - * variable. So I have a static version here which does. This code - * is based on NSPR's, and uses the NSPR function to initialize the - * required lock. - */ - -/* - * The is the "once block" that's passed to the "real" PR_CallOnce - * function, to call the local initializer myOnceFunction once. - */ -static PRCallOnceType myCallOnce; - -/* - * This structure is used by the call_once function to make sure that - * any "other" threads calling the call_once don't return too quickly, - * before the initializer has finished. - */ -static struct { - PZLock *ml; - PZCondVar *cv; -} mod_init; - -/* - * This is the initializer for the above mod_init structure. - */ -static PRStatus -myOnceFunction -( - void -) -{ - mod_init.ml = PZ_NewLock(nssILockOther); - if( (PZLock *)NULL == mod_init.ml ) { - return PR_FAILURE; - } - - mod_init.cv = PZ_NewCondVar(mod_init.ml); - if( (PZCondVar *)NULL == mod_init.cv ) { - PZ_DestroyLock(mod_init.ml); - mod_init.ml = (PZLock *)NULL; - return PR_FAILURE; - } - - return PR_SUCCESS; -} - -/* - * The nss call_once callback takes a closure argument. - */ -typedef PRStatus (PR_CALLBACK *nssCallOnceFN)(void *arg); - -/* - * NSS's call_once function. - */ -static PRStatus -call_once -( - PRCallOnceType *once, - nssCallOnceFN func, - void *arg -) -{ - PRStatus rv; - - if( !myCallOnce.initialized ) { - rv = PR_CallOnce(&myCallOnce, myOnceFunction); - if( PR_SUCCESS != rv ) { - return rv; - } - } - - if( !once->initialized ) { - if( 0 == PR_AtomicSet(&once->inProgress, 1) ) { - once->status = (*func)(arg); - PZ_Lock(mod_init.ml); - once->initialized = 1; - PZ_NotifyAllCondVar(mod_init.cv); - PZ_Unlock(mod_init.ml); - } else { - PZ_Lock(mod_init.ml); - while( !once->initialized ) { - PZ_WaitCondVar(mod_init.cv, PR_INTERVAL_NO_TIMEOUT); - } - PZ_Unlock(mod_init.ml); - } - } - - return once->status; -} - -/* - * Now we actually get to my own "call once" payload function. - * But wait, to create the hash, I need a hash function! - */ - /* * identity_hash * @@ -230,7 +131,7 @@ nssPointerTracker_initialize nssPointerTracker *tracker ) { - PRStatus rv = call_once(&tracker->once, trackerOnceFunc, tracker); + PRStatus rv = PR_CallOnceWithArg(&tracker->once, trackerOnceFunc, tracker); if( PR_SUCCESS != rv ) { nss_SetError(NSS_ERROR_NO_MEMORY); } diff --git a/mozilla/security/nss/lib/nss/nssinit.c b/mozilla/security/nss/lib/nss/nssinit.c index 39a17c216f7..6c08c3d36b3 100644 --- a/mozilla/security/nss/lib/nss/nssinit.c +++ b/mozilla/security/nss/lib/nss/nssinit.c @@ -36,7 +36,7 @@ * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ -/* $Id: nssinit.c,v 1.90 2008-02-16 04:38:06 julien.pierre.boogz%sun.com Exp $ */ +/* $Id: nssinit.c,v 1.91 2008-02-23 05:29:39 nelson%bolyard.com Exp $ */ #include #include "seccomon.h" @@ -837,6 +837,7 @@ NSS_Shutdown(void) shutdownRV = SECFailure; } pk11sdr_Shutdown(); + nssArena_Shutdown(); if (status == PR_FAILURE) { if (NSS_GetError() == NSS_ERROR_BUSY) { PORT_SetError(SEC_ERROR_BUSY);