} // can only be instantaited by self public static IDataProtector GetDataProtector(ref DataProtectorHelper helperRef, IDataProtectionProvider protectionProvider, IFactorySupportFunctions supportFunctions) { // First, make sure that only one thread ever initializes the helper instance. var helper = Volatile.Read(ref helperRef); if (helper == null) { var newHelper = new DataProtectorHelper(); helper = Interlocked.CompareExchange(ref helperRef, newHelper, null) ?? newHelper; } // Has the protector already been created? var protector = Volatile.Read(ref helper._dataProtector); if (protector == null) { // Since the helper is accessed by reference, all threads should agree on the one true helper // instance, so this lock is global given a particular reference. This is an implementation // of the double-check lock pattern. lock (helper) { protector = Volatile.Read(ref helper._dataProtector); if (protector == null) { protector = supportFunctions.CreateDataProtector(protectionProvider); Volatile.Write(ref helper._dataProtector, protector); } } } // And we're done! Debug.Assert(protector != null); return(protector); }
private IDataProtector GetCachedDataProtector() { var dataProtectionProvider = DataProtectionProviderHelper.GetDataProtectionProvider(ref _staticHelper, this); return(DataProtectorHelper.GetDataProtector(ref _helper, dataProtectionProvider, this)); }