Ejemplo n.º 1
0
        /// <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);
                }
        }
Ejemplo n.º 2
0
        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);
                }
            }
        }
Ejemplo n.º 3
0
        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);
        }
Ejemplo n.º 5
0
        /// <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);
        }
Ejemplo n.º 6
0
        /// <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;
            }
        }
Ejemplo n.º 7
0
 /// <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);
     }
 }
Ejemplo n.º 8
0
        /// <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);
                }
        }
Ejemplo n.º 9
0
        /// <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));
            }
        }
Ejemplo n.º 10
0
        /// <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());
             }
         }
     }
 }
Ejemplo n.º 12
0
        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());
                    }
                }
            }
        }
Ejemplo n.º 14
0
        /// <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);
                        }
                    }
                }
            }
        }
Ejemplo n.º 16
0
        /// <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;
            }
        }
Ejemplo n.º 18
0
        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);
        }
Ejemplo n.º 19
0
        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);
        }
Ejemplo n.º 20
0
        /// <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));
            }
        }