1 diff -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 21 diff -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 35 diff -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 204 diff -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