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