1diff --git a/nss/lib/ssl/ssl3con.c b/nss/lib/ssl/ssl3con.c 2index 53c29f0..bc54c99 100644 3--- a/nss/lib/ssl/ssl3con.c 4+++ b/nss/lib/ssl/ssl3con.c 5@@ -5593,7 +5593,6 @@ SSL3_ShutdownServerCache(void) 6 } 7 8 PZ_Unlock(symWrapKeysLock); 9- ssl_FreeSessionCacheLocks(); 10 return SECSuccess; 11 } 12 13@@ -5645,7 +5644,7 @@ getWrappingKey( sslSocket * ss, 14 15 pSymWrapKey = &symWrapKeys[symWrapMechIndex].symWrapKey[exchKeyType]; 16 17- ssl_InitSessionCacheLocks(PR_TRUE); 18+ ssl_InitSessionCacheLocks(); 19 20 PZ_Lock(symWrapKeysLock); 21 22diff --git a/nss/lib/ssl/sslimpl.h b/nss/lib/ssl/sslimpl.h 23index e3ae9ce..59140f8 100644 24--- a/nss/lib/ssl/sslimpl.h 25+++ b/nss/lib/ssl/sslimpl.h 26@@ -1845,9 +1845,7 @@ extern SECStatus ssl_InitSymWrapKeysLock(void); 27 28 extern SECStatus ssl_FreeSymWrapKeysLock(void); 29 30-extern SECStatus ssl_InitSessionCacheLocks(PRBool lazyInit); 31- 32-extern SECStatus ssl_FreeSessionCacheLocks(void); 33+extern SECStatus ssl_InitSessionCacheLocks(void); 34 35 /***************** platform client auth ****************/ 36 37diff --git a/nss/lib/ssl/sslnonce.c b/nss/lib/ssl/sslnonce.c 38index 5d8a954..a6f7349 100644 39--- a/nss/lib/ssl/sslnonce.c 40+++ b/nss/lib/ssl/sslnonce.c 41@@ -35,91 +35,55 @@ static PZLock * cacheLock = NULL; 42 #define LOCK_CACHE lock_cache() 43 #define UNLOCK_CACHE PZ_Unlock(cacheLock) 44 45+static PRCallOnceType lockOnce; 46+ 47+/* FreeSessionCacheLocks is a callback from NSS_RegisterShutdown which destroys 48+ * the session cache locks on shutdown and resets them to their initial 49+ * state. */ 50 static SECStatus 51-ssl_InitClientSessionCacheLock(void) 52+FreeSessionCacheLocks(void* appData, void* nssData) 53 { 54+ static const PRCallOnceType pristineCallOnce; 55+ SECStatus rv; 56+ 57+ if (!cacheLock) { 58+ PORT_SetError(SEC_ERROR_NOT_INITIALIZED); 59+ return SECFailure; 60+ } 61+ 62+ PZ_DestroyLock(cacheLock); 63+ cacheLock = NULL; 64+ 65+ rv = ssl_FreeSymWrapKeysLock(); 66+ if (rv != SECSuccess) { 67+ return rv; 68+ } 69+ 70+ lockOnce = pristineCallOnce; 71+ return SECSuccess; 72+} 73+ 74+/* InitSessionCacheLocks is called, protected by lockOnce, to create the 75+ * session cache locks. */ 76+static PRStatus 77+InitSessionCacheLocks(void) 78+{ 79+ SECStatus rv; 80+ 81 cacheLock = PZ_NewLock(nssILockCache); 82- return cacheLock ? SECSuccess : SECFailure; 83-} 84- 85-static SECStatus 86-ssl_FreeClientSessionCacheLock(void) 87-{ 88- if (cacheLock) { 89+ if (cacheLock == NULL) { 90+ return PR_FAILURE; 91+ } 92+ rv = ssl_InitSymWrapKeysLock(); 93+ if (rv != SECSuccess) { 94+ PRErrorCode error = PORT_GetError(); 95 PZ_DestroyLock(cacheLock); 96 cacheLock = NULL; 97- return SECSuccess; 98- } 99- PORT_SetError(SEC_ERROR_NOT_INITIALIZED); 100- return SECFailure; 101-} 102- 103-static PRBool LocksInitializedEarly = PR_FALSE; 104- 105-static SECStatus 106-FreeSessionCacheLocks() 107-{ 108- SECStatus rv1, rv2; 109- rv1 = ssl_FreeSymWrapKeysLock(); 110- rv2 = ssl_FreeClientSessionCacheLock(); 111- if ( (SECSuccess == rv1) && (SECSuccess == rv2) ) { 112- return SECSuccess; 113- } 114- return SECFailure; 115-} 116- 117-static SECStatus 118-InitSessionCacheLocks(void) 119-{ 120- SECStatus rv1, rv2; 121- PRErrorCode rc; 122- rv1 = ssl_InitSymWrapKeysLock(); 123- rv2 = ssl_InitClientSessionCacheLock(); 124- if ( (SECSuccess == rv1) && (SECSuccess == rv2) ) { 125- return SECSuccess; 126- } 127- rc = PORT_GetError(); 128- FreeSessionCacheLocks(); 129- PORT_SetError(rc); 130- return SECFailure; 131-} 132- 133-/* free the session cache locks if they were initialized early */ 134-SECStatus 135-ssl_FreeSessionCacheLocks() 136-{ 137- PORT_Assert(PR_TRUE == LocksInitializedEarly); 138- if (!LocksInitializedEarly) { 139- PORT_SetError(SEC_ERROR_NOT_INITIALIZED); 140- return SECFailure; 141- } 142- FreeSessionCacheLocks(); 143- LocksInitializedEarly = PR_FALSE; 144- return SECSuccess; 145-} 146- 147-static PRCallOnceType lockOnce; 148- 149-/* free the session cache locks if they were initialized lazily */ 150-static SECStatus ssl_ShutdownLocks(void* appData, void* nssData) 151-{ 152- PORT_Assert(PR_FALSE == LocksInitializedEarly); 153- if (LocksInitializedEarly) { 154- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); 155- return SECFailure; 156- } 157- FreeSessionCacheLocks(); 158- memset(&lockOnce, 0, sizeof(lockOnce)); 159- return SECSuccess; 160-} 161- 162-static PRStatus initSessionCacheLocksLazily(void) 163-{ 164- SECStatus rv = InitSessionCacheLocks(); 165- if (SECSuccess != rv) { 166+ PORT_SetError(error); 167 return PR_FAILURE; 168 } 169- rv = NSS_RegisterShutdown(ssl_ShutdownLocks, NULL); 170+ 171+ rv = NSS_RegisterShutdown(FreeSessionCacheLocks, NULL); 172 PORT_Assert(SECSuccess == rv); 173 if (SECSuccess != rv) { 174 return PR_FAILURE; 175@@ -127,34 +91,18 @@ static PRStatus initSessionCacheLocksLazily(void) 176 return PR_SUCCESS; 177 } 178 179-/* lazyInit means that the call is not happening during a 1-time 180- * initialization function, but rather during dynamic, lazy initialization 181- */ 182 SECStatus 183-ssl_InitSessionCacheLocks(PRBool lazyInit) 184+ssl_InitSessionCacheLocks(void) 185 { 186- if (LocksInitializedEarly) { 187- return SECSuccess; 188- } 189- 190- if (lazyInit) { 191- return (PR_SUCCESS == 192- PR_CallOnce(&lockOnce, initSessionCacheLocksLazily)) ? 193- SECSuccess : SECFailure; 194- } 195- 196- if (SECSuccess == InitSessionCacheLocks()) { 197- LocksInitializedEarly = PR_TRUE; 198- return SECSuccess; 199- } 200- 201- return SECFailure; 202+ return (PR_SUCCESS == 203+ PR_CallOnce(&lockOnce, InitSessionCacheLocks)) ? 204+ SECSuccess : SECFailure; 205 } 206 207-static void 208+static void 209 lock_cache(void) 210 { 211- ssl_InitSessionCacheLocks(PR_TRUE); 212+ ssl_InitSessionCacheLocks(); 213 PZ_Lock(cacheLock); 214 } 215 216diff --git a/nss/lib/ssl/sslsnce.c b/nss/lib/ssl/sslsnce.c 217index b0446ad..34e07b0 100644 218--- a/nss/lib/ssl/sslsnce.c 219+++ b/nss/lib/ssl/sslsnce.c 220@@ -1353,7 +1353,7 @@ SSL_ConfigServerSessionIDCache( int maxCacheEntries, 221 PRUint32 ssl3_timeout, 222 const char * directory) 223 { 224- ssl_InitSessionCacheLocks(PR_FALSE); 225+ ssl_InitSessionCacheLocks(); 226 return SSL_ConfigServerSessionIDCacheInstance(&globalCache, 227 maxCacheEntries, ssl2_timeout, ssl3_timeout, directory, PR_FALSE); 228 } 229@@ -1467,7 +1467,7 @@ SSL_ConfigServerSessionIDCacheWithOpt( 230 PRBool enableMPCache) 231 { 232 if (!enableMPCache) { 233- ssl_InitSessionCacheLocks(PR_FALSE); 234+ ssl_InitSessionCacheLocks(); 235 return ssl_ConfigServerSessionIDCacheInstanceWithOpt(&globalCache, 236 ssl2_timeout, ssl3_timeout, directory, PR_FALSE, 237 maxCacheEntries, maxCertCacheEntries, maxSrvNameCacheEntries); 238@@ -1512,7 +1512,7 @@ SSL_InheritMPServerSIDCacheInstance(cacheDesc *cache, const char * envString) 239 return SECSuccess; /* already done. */ 240 } 241 242- ssl_InitSessionCacheLocks(PR_FALSE); 243+ ssl_InitSessionCacheLocks(); 244 245 ssl_sid_lookup = ServerSessionIDLookup; 246 ssl_sid_cache = ServerSessionIDCache; 247