/// <summary> /// Inserts a type before a specified, already existing type. /// </summary> /// <param name="existingType">The existing type before which to insert.</param> /// <param name="value">The type to insert.</param> /// <exception cref="InvalidOperationException">the resolver does not support inserting types, or /// one of the types is not a valid type for the resolver, or the existing type is not in the collection, /// or the new type is already in the collection of types.</exception> public virtual void InsertTypeBefore(Type existingType, Type value) { EnsureSupportsInsert(); using (Resolution.Configuration) using (var l = new UpgradeableReadLock(_lock)) { EnsureCorrectType(existingType); EnsureCorrectType(value); if (!_instanceTypes.Contains(existingType)) { throw new InvalidOperationException(string.Format( "Type {0} is not in the collection of types.", existingType.FullName)); } if (_instanceTypes.Contains(value)) { throw new InvalidOperationException(string.Format( "Type {0} is already in the collection of types.", value.FullName)); } int index = _instanceTypes.IndexOf(existingType); l.UpgradeToWriteLock(); _instanceTypes.Insert(index, value); } }
public void Update(Controllers.BaseControllers controllers, GameObject ownerEnt, double dt) { using (UpgradeableReadLock.CreateLock(m_componentsAddQueueLock)) { foreach (var comp in m_componentsAddQueue) { AddComponent(comp); } using (WriteLock.CreateLock(m_componentsAddQueueLock)) { m_componentsAddQueue.Clear(); } } using (WriteLock.CreateLock(m_componentsRemoveQueueLock)) { foreach (var comp in m_componentsRemoveQueue) { m_componentsSorted.Remove(comp); } m_componentsRemoveQueue.Clear(); } using (ReadLock.CreateLock(m_componentsSortedLock)) { foreach (var component in m_componentsSorted) { component.Value.Tick(controllers, ownerEnt, dt); } } }
public object GetCacheItem( string cacheKey, Func <object> getCacheItem, TimeSpan?timeout, bool isSliding = false, CacheItemPriority priority = CacheItemPriority.Normal, CacheItemRemovedCallback removedCallback = null, string[] dependentFiles = null) { using (var lck = new UpgradeableReadLock(Locker)) { var result = MemoryCache.Get(cacheKey); if (result == null) { lck.UpgradeToWriteLock(); result = getCacheItem(); if (result != null) { var policy = GetPolicy(timeout, isSliding, removedCallback, dependentFiles); MemoryCache.Set(cacheKey, result, policy); } } return(result); } }
public object GetCacheItem(string cacheKey, Func <object> getCacheItem, TimeSpan?timeout, bool isSliding = false, CacheItemPriority priority = CacheItemPriority.Normal, CacheItemRemovedCallback removedCallback = null, string[] dependentFiles = null) { // see notes in HttpRuntimeCacheProvider Lazy <object> result; using (var lck = new UpgradeableReadLock(_locker)) { result = MemoryCache.Get(cacheKey) as Lazy <object>; if (result == null || DictionaryCacheProviderBase.GetSafeLazyValue(result, true) == null) // get non-created as NonCreatedValue & exceptions as null { result = DictionaryCacheProviderBase.GetSafeLazy(getCacheItem); var policy = GetPolicy(timeout, isSliding, removedCallback, dependentFiles); lck.UpgradeToWriteLock(); //NOTE: This does an add or update MemoryCache.Set(cacheKey, result, policy); } } //return result.Value; var value = result.Value; // will not throw (safe lazy) var eh = value as DictionaryCacheProviderBase.ExceptionHolder; if (eh != null) { throw eh.Exception; // throw once! } return(value); }
/// <inheritdoc /> public object Get(string key, Func <object> factory, TimeSpan?timeout, bool isSliding = false, string[] dependentFiles = null) { // see notes in HttpRuntimeAppCache Lazy <object> result; using (var lck = new UpgradeableReadLock(_locker)) { result = MemoryCache.Get(key) as Lazy <object>; if (result == null || SafeLazy.GetSafeLazyValue(result, true) == null) // get non-created as NonCreatedValue & exceptions as null { result = SafeLazy.GetSafeLazy(factory); var policy = GetPolicy(timeout, isSliding, dependentFiles); lck.UpgradeToWriteLock(); //NOTE: This does an add or update MemoryCache.Set(key, result, policy); } } //return result.Value; var value = result.Value; // will not throw (safe lazy) if (value is SafeLazy.ExceptionHolder eh) { eh.Exception.Throw(); // throw once! } return(value); }
/// <summary> /// Reads all items from the database and stores in local cache /// </summary> private static void EnsureCache() { using (var lck = new UpgradeableReadLock(Locker)) { if (_cacheIsEnsured) { return; } lck.UpgradeToWriteLock(); using (var dr = SqlHelper.ExecuteReader("Select pk, id, [key], parent from cmsDictionary")) { while (dr.Read()) { //create new dictionaryitem object and put in cache var item = new DictionaryItem(dr.GetInt("pk"), dr.GetString("key"), dr.GetGuid("id"), dr.GetGuid("parent")); DictionaryItems.TryAdd(item.key, item); } } _cacheIsEnsured = true; } }
/// <summary> /// Removes a type. /// </summary> /// <param name="value">The type to remove.</param> /// <exception cref="InvalidOperationException">the resolver does not support removing types, or /// the type is not a valid type for the resolver.</exception> public virtual void RemoveType(Type value) { using (var l = new UpgradeableReadLock(_lock)) { l.UpgradeToWriteLock(); _instanceTypes.Remove(value); } }
/// <summary> /// Removes a type. /// </summary> /// <param name="value">The type to remove.</param> /// <exception cref="InvalidOperationException">the resolver does not support removing types, or /// the type is not a valid type for the resolver.</exception> public virtual void RemoveType(Type value) { EnsureSupportsRemove(); using (Resolution.Configuration) using (var l = new UpgradeableReadLock(_lock)) { EnsureCorrectType(value); l.UpgradeToWriteLock(); _instanceTypes.Remove(value); } }
/// <summary> /// Finds all instances of ITree in loaded assemblies, then finds their associated ApplicationTree and Application objects /// and stores them together in a TreeDefinition class and adds the definition to our list. /// This will also store an instance of each tree object in the TreeDefinition class which should be /// used when referencing all tree classes. /// </summary> private void EnsureTreesRegistered(bool clearFirst = false) { using (var l = new UpgradeableReadLock(Lock)) { if (clearFirst) { this.Clear(); } //if we already have tree, exit if (this.Count > 0) { return; } l.UpgradeToWriteLock(); var foundITrees = PluginManager.Current.ResolveTrees(); var objTrees = ApplicationTree.getAll(); var appTrees = new List <ApplicationTree>(); appTrees.AddRange(objTrees); var apps = Application.getAll(); foreach (var type in foundITrees) { //find the Application tree's who's combination of assembly name and tree type is equal to //the Type that was found's full name. //Since a tree can exist in multiple applications we'll need to register them all. var appTreesForType = appTrees.FindAll( tree => (string.Format("{0}.{1}", tree.AssemblyName, tree.Type) == type.FullName) ); foreach (var appTree in appTreesForType) { //find the Application object whos name is the same as our appTree ApplicationAlias var app = apps.Find( a => (a.alias == appTree.ApplicationAlias) ); var def = new TreeDefinition(type, appTree, app); this.Add(def); } } //sort our trees with the sort order definition this.Sort((t1, t2) => t1.Tree.SortOrder.CompareTo(t2.Tree.SortOrder)); } }
/// <summary> /// Adds a type. /// </summary> /// <param name="value">The type to add.</param> /// <remarks>The type is appended at the end of the list.</remarks> /// <exception cref="InvalidOperationException">the resolver does not support adding types, or /// the type is not a valid type for the resolver, or the type is already in the collection of types.</exception> public virtual void AddType(Type value) { using (var l = new UpgradeableReadLock(_lock)) { if (_instanceTypes.Contains(value)) { throw new InvalidOperationException(string.Format( "Type {0} is already in the collection of types.", value.FullName)); } l.UpgradeToWriteLock(); _instanceTypes.Add(value); } }
/// <summary> /// Populates the ids -> Type dictionary to allow us to instantiate a type by Id since these legacy types doesn't contain any metadata /// </summary> protected void EnsureIdsAreTracked() { using (var l = new UpgradeableReadLock(_lock)) { if (_trackIdToType == null) { l.UpgradeToWriteLock(); _trackIdToType = new ConcurrentDictionary <Guid, Type>(); foreach (var v in Values) { _trackIdToType.TryAdd(GetUniqueIdentifier(v), v.GetType()); } } } }
public void AddComponentAsType(EntityComponentBase component, Type type) { using (UpgradeableReadLock.CreateLock(m_componentsSortedLock)) { if (m_componentsSorted.ContainsKey(type.FullName.GetHashCode())) { return; } using (WriteLock.CreateLock(m_componentsSortedLock)) { m_componentsSorted[type.FullName.GetHashCode()] = component; } } }
/// <summary> /// Populates the identifiers-to-types dictionnary. /// </summary> /// <remarks> /// <para>This allow us to instantiate a type by ID since these legacy types doesn't contain any metadata.</para> /// <para>We instanciate all types once to get their unique identifier, then build the dictionary so that /// when GetById is called, we can instanciate a single object.</para> /// </remarks> protected void EnsureIsInitialized() { using (var l = new UpgradeableReadLock(_lock)) { if (_id2type == null) { l.UpgradeToWriteLock(); _id2type = new ConcurrentDictionary <Guid, Type>(); foreach (var value in Values) { _id2type.TryAdd(GetUniqueIdentifier(value), value.GetType()); } } } }
/// <summary> /// Adds a type. /// </summary> /// <param name="value">The type to add.</param> /// <remarks>The type is appended at the end of the list.</remarks> /// <exception cref="InvalidOperationException">the resolver does not support adding types, or /// the type is not a valid type for the resolver, or the type is already in the collection of types.</exception> public virtual void AddType(Type value) { EnsureSupportsAdd(); using (Resolution.Configuration) using (var l = new UpgradeableReadLock(_lock)) { EnsureCorrectType(value); if (_instanceTypes.Contains(value)) { throw new InvalidOperationException(string.Format( "Type {0} is already in the collection of types.", value.FullName)); } l.UpgradeToWriteLock(); _instanceTypes.Add(value); } }
static void UmbracoModuleRouteAttempt(object sender, Routing.RoutableAttemptEventArgs e) { if (e.HttpContext.Request == null || e.HttpContext.Request.Url == null) { return; } if (e.Outcome == EnsureRoutableOutcome.IsRoutable) { using (var lck = new UpgradeableReadLock(Locker)) { //we only want to do the initial update once if (!_initUpdated) { lck.UpgradeToWriteLock(); _initUpdated = true; UpdateServerEntry(e.HttpContext, e.UmbracoContext.Application); return; } } } //if it is not a document request, we'll check if it is a back end request if (e.Outcome == EnsureRoutableOutcome.NotDocumentRequest) { //check if this is in the umbraco back office if (e.HttpContext.Request.Url.IsBackOfficeRequest()) { //yup it's a back office request! using (var lck = new UpgradeableReadLock(Locker)) { //we don't want to update if it's not been at least a minute since last time var isItAMinute = DateTime.Now.Subtract(_lastUpdated).TotalSeconds >= 60; if (isItAMinute) { lck.UpgradeToWriteLock(); _initUpdated = true; _lastUpdated = DateTime.Now; UpdateServerEntry(e.HttpContext, e.UmbracoContext.Application); } } } } }
/// <summary> /// Inserts a Type at the specified index. /// </summary> /// <param name="index">The zero-based index at which the object should be inserted.</param> /// <param name="value">The object to insert.</param> public void InsertType(int index, Type value) { if (!SupportsInsert) { throw new InvalidOperationException("This resolver does not support Inserting new types"); } using (var l = new UpgradeableReadLock(_lock)) { EnsureCorrectType(value); if (InstanceTypes.Contains(value)) { throw new InvalidOperationException("The Type " + value + " already exists in the collection"); } ; l.UpgradeToWriteLock(); InstanceTypes.Insert(index, value); } }
internal static void EnsureInitialize() { using (var lck = new UpgradeableReadLock(Lock)) { if (_isInitialized) { return; } lck.UpgradeToWriteLock(); AllEngines.Clear(); AllEngines.AddRange( PluginManager.Current.CreateInstances <IMacroEngine>( PluginManager.Current.ResolveMacroEngines())); _isInitialized = true; } }
public object GetCacheItem(string cacheKey, Func <object> getCacheItem, TimeSpan?timeout, bool isSliding = false, CacheItemPriority priority = CacheItemPriority.Normal, CacheItemRemovedCallback removedCallback = null, string[] dependentFiles = null) { // see notes in HttpRuntimeCacheProvider Lazy <object> result; using (var lck = new UpgradeableReadLock(_locker)) { result = MemoryCache.Get(cacheKey) as Lazy <object>; if (result == null || GetSafeLazyValue(result, true) == null) // get non-created as NonCreatedValue & exceptions as null { result = new Lazy <object>(getCacheItem); var policy = GetPolicy(timeout, isSliding, removedCallback, dependentFiles); lck.UpgradeToWriteLock(); MemoryCache.Set(cacheKey, result, policy); } } return(result.Value); }
private object GetImpl(string key, Func <object> factory, TimeSpan?timeout, bool isSliding = false, CacheDependency dependency = null) { key = GetCacheKey(key); // NOTE - because we don't know what getCacheItem does, how long it will take and whether it will hang, // getCacheItem should run OUTSIDE of the global application lock else we run into lock contention and // nasty performance issues. // So.... we insert a Lazy<object> in the cache while holding the global application lock, and then rely // on the Lazy lock to ensure that getCacheItem runs once and everybody waits on it, while the global // application lock has been released. // NOTE // The Lazy value creation may produce a null value. // Must make sure (for backward compatibility) that we pretend they are not in the cache. // So if we find an entry in the cache that already has its value created and is null, // pretend it was not there. If value is not already created, wait... and return null, that's // what prior code did. // NOTE // The Lazy value creation may throw. // So... the null value _will_ be in the cache but never returned Lazy <object> result; // Fast! // Only one thread can enter an UpgradeableReadLock at a time, but it does not prevent other // threads to enter a ReadLock in the meantime -- only upgrading to WriteLock will prevent all // reads. We first try with a normal ReadLock for maximum concurrency and take the penalty of // having to re-lock in case there's no value. Would need to benchmark to figure out whether // it's worth it, though... try { _locker.EnterReadLock(); result = _cache.Get(key) as Lazy <object>; // null if key not found } finally { if (_locker.IsReadLockHeld) { _locker.ExitReadLock(); } } var value = result == null ? null : SafeLazy.GetSafeLazyValue(result); if (value != null) { return(value); } using (var lck = new UpgradeableReadLock(_locker)) { result = _cache.Get(key) as Lazy <object>; // null if key not found // cannot create value within the lock, so if result.IsValueCreated is false, just // do nothing here - means that if creation throws, a race condition could cause // more than one thread to reach the return statement below and throw - accepted. if (result == null || SafeLazy.GetSafeLazyValue(result, true) == null) // get non-created as NonCreatedValue & exceptions as null { result = SafeLazy.GetSafeLazy(factory); var absolute = isSliding ? System.Web.Caching.Cache.NoAbsoluteExpiration : (timeout == null ? System.Web.Caching.Cache.NoAbsoluteExpiration : DateTime.Now.Add(timeout.Value)); var sliding = isSliding == false ? System.Web.Caching.Cache.NoSlidingExpiration : (timeout ?? System.Web.Caching.Cache.NoSlidingExpiration); lck.UpgradeToWriteLock(); //NOTE: 'Insert' on System.Web.Caching.Cache actually does an add or update! _cache.Insert(key, result, dependency, absolute, sliding, CacheItemPriority.Normal, null); } } // using GetSafeLazy and GetSafeLazyValue ensures that we don't cache // exceptions (but try again and again) and silently eat them - however at // some point we have to report them - so need to re-throw here // this does not throw anymore //return result.Value; value = result.Value; // will not throw (safe lazy) if (value is SafeLazy.ExceptionHolder eh) { eh.Exception.Throw(); // throw once! } return(value); }
/// <summary> /// Finds all instances of ITree in loaded assemblies, then finds their associated ApplicationTree and Application objects /// and stores them together in a TreeDefinition class and adds the definition to our list. /// This will also store an instance of each tree object in the TreeDefinition class which should be /// used when referencing all tree classes. /// </summary> private void EnsureTreesRegistered(bool clearFirst = false) { using (var l = new UpgradeableReadLock(Lock)) { if (clearFirst) { this.Clear(); } //if we already have tree, exit if (this.Count > 0) { return; } l.UpgradeToWriteLock(); var foundITrees = PluginManager.Current.ResolveTrees(); var objTrees = ApplicationTree.getAll(); var appTrees = new List <ApplicationTree>(); appTrees.AddRange(objTrees); var apps = Application.getAll(); foreach (var type in foundITrees) { //find the Application tree's who's combination of assembly name and tree type is equal to //the Type that was found's full name. //Since a tree can exist in multiple applications we'll need to register them all. //The logic of this has changed in 6.0: http://issues.umbraco.org/issue/U4-1360 // we will support the old legacy way but the normal way is to match on assembly qualified names var appTreesForType = appTrees.FindAll( tree => { //match the type on assembly qualified name if the assembly attribute is empty or if the // tree type contains a comma (meaning it is assembly qualified) if (tree.AssemblyName.IsNullOrWhiteSpace() || tree.Type.Contains(",")) { return(tree.Type == type.GetFullNameWithAssembly()); } //otherwise match using legacy match rules return(string.Format("{0}.{1}", tree.AssemblyName, tree.Type).InvariantEquals(type.FullName)); } ); foreach (var appTree in appTreesForType) { //find the Application object whos name is the same as our appTree ApplicationAlias var app = apps.Find( a => (a.alias == appTree.ApplicationAlias) ); var def = new TreeDefinition(type, appTree, app); this.Add(def); } } //sort our trees with the sort order definition this.Sort((t1, t2) => t1.Tree.SortOrder.CompareTo(t2.Tree.SortOrder)); } }