| diff --git a/lib/ssl/ssl3con.c b/lib/ssl/ssl3con.c |
| index 2533679..ba3d012 100644 |
| --- a/lib/ssl/ssl3con.c |
| +++ b/lib/ssl/ssl3con.c |
| @@ -5921,7 +5921,6 @@ SSL3_ShutdownServerCache(void) |
| } |
| |
| PZ_Unlock(symWrapKeysLock); |
| - ssl_FreeSessionCacheLocks(); |
| return SECSuccess; |
| } |
| |
| @@ -5973,7 +5972,7 @@ getWrappingKey( sslSocket * ss, |
| |
| pSymWrapKey = &symWrapKeys[symWrapMechIndex].symWrapKey[exchKeyType]; |
| |
| - ssl_InitSessionCacheLocks(PR_TRUE); |
| + ssl_InitSessionCacheLocks(); |
| |
| PZ_Lock(symWrapKeysLock); |
| |
| diff --git a/lib/ssl/sslimpl.h b/lib/ssl/sslimpl.h |
| index d5f326f..d53c446 100644 |
| --- a/lib/ssl/sslimpl.h |
| +++ b/lib/ssl/sslimpl.h |
| @@ -1957,9 +1957,7 @@ extern SECStatus ssl_InitSymWrapKeysLock(void); |
| |
| extern SECStatus ssl_FreeSymWrapKeysLock(void); |
| |
| -extern SECStatus ssl_InitSessionCacheLocks(PRBool lazyInit); |
| - |
| -extern SECStatus ssl_FreeSessionCacheLocks(void); |
| +extern SECStatus ssl_InitSessionCacheLocks(void); |
| |
| /***************** platform client auth ****************/ |
| |
| diff --git a/lib/ssl/sslnonce.c b/lib/ssl/sslnonce.c |
| index 1326a8b..c45849d 100644 |
| --- a/lib/ssl/sslnonce.c |
| +++ b/lib/ssl/sslnonce.c |
| @@ -35,91 +35,55 @@ static PZLock * cacheLock = NULL; |
| #define LOCK_CACHE lock_cache() |
| #define UNLOCK_CACHE PZ_Unlock(cacheLock) |
| |
| -static SECStatus |
| -ssl_InitClientSessionCacheLock(void) |
| -{ |
| - cacheLock = PZ_NewLock(nssILockCache); |
| - return cacheLock ? SECSuccess : SECFailure; |
| -} |
| - |
| -static SECStatus |
| -ssl_FreeClientSessionCacheLock(void) |
| -{ |
| - if (cacheLock) { |
| - PZ_DestroyLock(cacheLock); |
| - cacheLock = NULL; |
| - return SECSuccess; |
| - } |
| - PORT_SetError(SEC_ERROR_NOT_INITIALIZED); |
| - return SECFailure; |
| -} |
| - |
| -static PRBool LocksInitializedEarly = PR_FALSE; |
| +static PRCallOnceType lockOnce; |
| |
| +/* FreeSessionCacheLocks is a callback from NSS_RegisterShutdown which destroys |
| + * the session cache locks on shutdown and resets them to their initial |
| + * state. */ |
| static SECStatus |
| -FreeSessionCacheLocks() |
| +FreeSessionCacheLocks(void* appData, void* nssData) |
| { |
| - SECStatus rv1, rv2; |
| - rv1 = ssl_FreeSymWrapKeysLock(); |
| - rv2 = ssl_FreeClientSessionCacheLock(); |
| - if ( (SECSuccess == rv1) && (SECSuccess == rv2) ) { |
| - return SECSuccess; |
| - } |
| - return SECFailure; |
| -} |
| + static const PRCallOnceType pristineCallOnce; |
| + SECStatus rv; |
| |
| -static SECStatus |
| -InitSessionCacheLocks(void) |
| -{ |
| - SECStatus rv1, rv2; |
| - PRErrorCode rc; |
| - rv1 = ssl_InitSymWrapKeysLock(); |
| - rv2 = ssl_InitClientSessionCacheLock(); |
| - if ( (SECSuccess == rv1) && (SECSuccess == rv2) ) { |
| - return SECSuccess; |
| - } |
| - rc = PORT_GetError(); |
| - FreeSessionCacheLocks(); |
| - PORT_SetError(rc); |
| - return SECFailure; |
| -} |
| - |
| -/* free the session cache locks if they were initialized early */ |
| -SECStatus |
| -ssl_FreeSessionCacheLocks() |
| -{ |
| - PORT_Assert(PR_TRUE == LocksInitializedEarly); |
| - if (!LocksInitializedEarly) { |
| + if (!cacheLock) { |
| PORT_SetError(SEC_ERROR_NOT_INITIALIZED); |
| return SECFailure; |
| } |
| - FreeSessionCacheLocks(); |
| - LocksInitializedEarly = PR_FALSE; |
| - return SECSuccess; |
| -} |
| |
| -static PRCallOnceType lockOnce; |
| + PZ_DestroyLock(cacheLock); |
| + cacheLock = NULL; |
| |
| -/* free the session cache locks if they were initialized lazily */ |
| -static SECStatus ssl_ShutdownLocks(void* appData, void* nssData) |
| -{ |
| - PORT_Assert(PR_FALSE == LocksInitializedEarly); |
| - if (LocksInitializedEarly) { |
| - PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); |
| - return SECFailure; |
| + rv = ssl_FreeSymWrapKeysLock(); |
| + if (rv != SECSuccess) { |
| + return rv; |
| } |
| - FreeSessionCacheLocks(); |
| - memset(&lockOnce, 0, sizeof(lockOnce)); |
| + |
| + lockOnce = pristineCallOnce; |
| return SECSuccess; |
| } |
| |
| -static PRStatus initSessionCacheLocksLazily(void) |
| +/* InitSessionCacheLocks is called, protected by lockOnce, to create the |
| + * session cache locks. */ |
| +static PRStatus |
| +InitSessionCacheLocks(void) |
| { |
| - SECStatus rv = InitSessionCacheLocks(); |
| - if (SECSuccess != rv) { |
| + SECStatus rv; |
| + |
| + cacheLock = PZ_NewLock(nssILockCache); |
| + if (cacheLock == NULL) { |
| return PR_FAILURE; |
| } |
| - rv = NSS_RegisterShutdown(ssl_ShutdownLocks, NULL); |
| + rv = ssl_InitSymWrapKeysLock(); |
| + if (rv != SECSuccess) { |
| + PRErrorCode error = PORT_GetError(); |
| + PZ_DestroyLock(cacheLock); |
| + cacheLock = NULL; |
| + PORT_SetError(error); |
| + return PR_FAILURE; |
| + } |
| + |
| + rv = NSS_RegisterShutdown(FreeSessionCacheLocks, NULL); |
| PORT_Assert(SECSuccess == rv); |
| if (SECSuccess != rv) { |
| return PR_FAILURE; |
| @@ -127,34 +91,18 @@ static PRStatus initSessionCacheLocksLazily(void) |
| return PR_SUCCESS; |
| } |
| |
| -/* lazyInit means that the call is not happening during a 1-time |
| - * initialization function, but rather during dynamic, lazy initialization |
| - */ |
| SECStatus |
| -ssl_InitSessionCacheLocks(PRBool lazyInit) |
| +ssl_InitSessionCacheLocks(void) |
| { |
| - if (LocksInitializedEarly) { |
| - return SECSuccess; |
| - } |
| - |
| - if (lazyInit) { |
| - return (PR_SUCCESS == |
| - PR_CallOnce(&lockOnce, initSessionCacheLocksLazily)) ? |
| - SECSuccess : SECFailure; |
| - } |
| - |
| - if (SECSuccess == InitSessionCacheLocks()) { |
| - LocksInitializedEarly = PR_TRUE; |
| - return SECSuccess; |
| - } |
| - |
| - return SECFailure; |
| + return (PR_SUCCESS == |
| + PR_CallOnce(&lockOnce, InitSessionCacheLocks)) ? |
| + SECSuccess : SECFailure; |
| } |
| |
| -static void |
| +static void |
| lock_cache(void) |
| { |
| - ssl_InitSessionCacheLocks(PR_TRUE); |
| + ssl_InitSessionCacheLocks(); |
| PZ_Lock(cacheLock); |
| } |
| |
| diff --git a/lib/ssl/sslsnce.c b/lib/ssl/sslsnce.c |
| index f31b2e9..3856c13 100644 |
| --- a/lib/ssl/sslsnce.c |
| +++ b/lib/ssl/sslsnce.c |
| @@ -1363,7 +1363,7 @@ SSL_ConfigServerSessionIDCache( int maxCacheEntries, |
| PRUint32 ssl3_timeout, |
| const char * directory) |
| { |
| - ssl_InitSessionCacheLocks(PR_FALSE); |
| + ssl_InitSessionCacheLocks(); |
| return SSL_ConfigServerSessionIDCacheInstance(&globalCache, |
| maxCacheEntries, ssl2_timeout, ssl3_timeout, directory, PR_FALSE); |
| } |
| @@ -1477,7 +1477,7 @@ SSL_ConfigServerSessionIDCacheWithOpt( |
| PRBool enableMPCache) |
| { |
| if (!enableMPCache) { |
| - ssl_InitSessionCacheLocks(PR_FALSE); |
| + ssl_InitSessionCacheLocks(); |
| return ssl_ConfigServerSessionIDCacheInstanceWithOpt(&globalCache, |
| ssl2_timeout, ssl3_timeout, directory, PR_FALSE, |
| maxCacheEntries, maxCertCacheEntries, maxSrvNameCacheEntries); |
| @@ -1521,7 +1521,7 @@ SSL_InheritMPServerSIDCacheInstance(cacheDesc *cache, const char * envString) |
| return SECSuccess; /* already done. */ |
| } |
| |
| - ssl_InitSessionCacheLocks(PR_FALSE); |
| + ssl_InitSessionCacheLocks(); |
| |
| ssl_sid_lookup = ServerSessionIDLookup; |
| ssl_sid_cache = ServerSessionIDCache; |