示例#1
0
        /// <summary>
        /// Initializes the contents of the stack from an existing collection.
        /// </summary>
        /// <param name="collection">A collection from which to copy elements.</param>
        private void InitializeFromCollection(IEnumerable <T> collection)
        {
            // We just copy the contents of the collection to our stack.
            Node lastNode = null;

            foreach (T element in collection)
            {
                Node newNode = (this.usePool == true ? PoolClassMainThread <Node> .Spawn() : new Node());
                newNode.m_value = element;
                newNode.m_next  = lastNode;
                lastNode        = newNode;
            }

            m_head = lastNode;
        }
示例#2
0
        /// <summary>
        /// Local helper function to Pop an item from the stack, slow path
        /// </summary>
        /// <param name="result">The popped item</param>
        /// <returns>True if succeeded, false otherwise</returns>
        private bool TryPopCore(out T result)
        {
            Node poppedNode;

            if (TryPopCore(1, out poppedNode) == 1)
            {
                result = poppedNode.m_value;
                if (this.usePool == true)
                {
                    PoolClassMainThread <Node> .Recycle(ref poppedNode);
                }
                return(true);
            }

            result = default(T);
            return(false);
        }
示例#3
0
        /// <summary>
        /// Inserts an object at the top of the <see cref="ConcurrentStack{T}"/>.
        /// </summary>
        /// <param name="item">The object to push onto the <see cref="ConcurrentStack{T}"/>. The value can be
        /// a null reference (Nothing in Visual Basic) for reference types.
        /// </param>
        public void Push(T item)
        {
            // Pushes a node onto the front of the stack thread-safely. Internally, this simply
            // swaps the current head pointer using a (thread safe) CAS operation to accomplish
            // lock freedom. If the CAS fails, we add some back off to statistically decrease
            // contention at the head, and then go back around and retry.

            Node newNode = (this.usePool == true ? PoolClassMainThread <Node> .Spawn() : new Node());

            newNode.m_value = item;
            newNode.m_next  = m_head;
            if (Interlocked.CompareExchange(ref m_head, newNode, newNode.m_next) == newNode.m_next)
            {
                return;
            }

            // If we failed, go to the slow path and loop around until we succeed.
            PushCore(newNode, newNode);
        }
示例#4
0
        /// <summary>
        /// Removes all objects from the <see cref="ConcurrentStack{T}"/>.
        /// </summary>
        public void Clear()
        {
            // Clear the list by setting the head to null. We don't need to use an atomic
            // operation for this: anybody who is mutating the head by pushing or popping
            // will need to use an atomic operation to guarantee they serialize and don't
            // overwrite our setting of the head to null.
            var current = this.m_head;

            this.m_head = null;

            if (this.usePool == true)
            {
                while (current != null)
                {
                    PoolClassMainThread <Node> .Recycle(ref current);

                    current = current.m_next;
                }
            }
        }
示例#5
0
        /// <summary>
        /// Attempts to pop and return the object at the top of the <see cref="ConcurrentStack{T}"/>.
        /// </summary>
        /// <param name="result">
        /// When this method returns, if the operation was successful, <paramref name="result"/> contains the
        /// object removed. If no object was available to be removed, the value is unspecified.
        /// </param>
        /// <returns>true if an element was removed and returned from the top of the <see
        /// cref="ConcurrentStack{T}"/>
        /// succesfully; otherwise, false.</returns>
        public bool TryPop(out T result)
        {
            Node head = m_head;

            //stack is empty
            if (head == null)
            {
                result = default(T);
                return(false);
            }
            if (Interlocked.CompareExchange(ref m_head, head.m_next, head) == head)
            {
                result = head.m_value;
                if (this.usePool == true)
                {
                    PoolClassMainThread <Node> .Recycle(ref head);
                }
                return(true);
            }

            // Fall through to the slow path.
            return(TryPopCore(out result));
        }