Ejemplo n.º 1
0
        /// <summary>
        /// thread safe method which adds the given node to the top of the list
        /// </summary>
        /// <param name="cachenode">node to be added, if the node is added by some other thread it returns</param>
        internal void AddFirst(LinkedListNode <CacheNode <T, V> > cachenode)
        {
            bool added      = false;
            int  retrycount = 0;

            do
            {
                bool             firstlocktaken = false;
                bool             nextlocktaken  = false;
                bool             curlocktaken   = false;
                CacheNode <T, V> nextNode       = null;
                try
                {
                    retrycount++;

                    firstlocktaken = FirstNode.Value.TryLock();
                    if (!firstlocktaken)
                    {
                        continue;
                    }
                    curlocktaken = cachenode.Value.TryLock();
                    if (!curlocktaken)
                    {
                        continue;
                    }
                    if (cachenode.List != null)
                    {
                        return;                         //added by another thread
                    }
                    if (FirstNode.Next == cachenode)
                    {
                        return;                              //no need for promotion
                    }
                    nextNode      = FirstNode.Next.Value;
                    nextlocktaken = nextNode.TryLock();
                    if (!nextlocktaken)
                    {
                        continue;
                    }

                    this.list.AddAfter(FirstNode, cachenode);
                    added = true;
                } finally
                {
                    if (nextlocktaken)
                    {
                        nextNode.UnlockNode();
                    }
                    if (curlocktaken)
                    {
                        cachenode.Value.UnlockNode();
                    }
                    if (firstlocktaken)
                    {
                        FirstNode.Value.UnlockNode();
                    }
                    if (retrycount % 100 == 0)
                    {
                        Logger.Info($"retryAddFirst {cachenode.Value.key} tries {retrycount}");
                    }
                    Thread.Sleep(0);
                }
            } while (!added);
        }