async Task <D2LSecurityToken> IPrivateKeyProvider.GetSigningCredentialsAsync() { // Hold a local reference so that we know we are talking about the same key // after even if another thread changed m_privateKey (race condition when we // are using a key very close to the rotation time.) D2LSecurityToken privateKey = m_privateKey; if (NeedFreshPrivateKey(privateKey)) { // This Semaphore is used instead of lock(foo){} // because await cannot be used within a lock await m_privateKeyLock.WaitAsync().SafeAsync(); try { privateKey = m_privateKey; if (NeedFreshPrivateKey(privateKey)) { m_privateKey = (await m_inner.GetSigningCredentialsAsync().SafeAsync()).Ref(); if (privateKey != null) { privateKey.Dispose(); } privateKey = m_privateKey; } } finally { m_privateKeyLock.Release(); } } return(privateKey.Ref()); }