/// <summary> /// Adds an object to the end of the queue. /// </summary> /// <param name="item">the object to add to the queue</param> public void Enqueue(T item) { SingleLinkNode <T> oldTail = null; SingleLinkNode <T> oldTailNext; var newNode = new SingleLinkNode <T> { Item = item }; bool newNodeWasAdded = false; while (!newNodeWasAdded) { oldTail = _tail; oldTailNext = oldTail.Next; if (_tail == oldTail) { if (oldTailNext == null) { newNodeWasAdded = Interlocked.CompareExchange <SingleLinkNode <T> >(ref _tail.Next, newNode, null) == null; } else { Interlocked.CompareExchange <SingleLinkNode <T> >(ref _tail, oldTailNext, oldTail); } } } Interlocked.CompareExchange <SingleLinkNode <T> >(ref _tail, newNode, oldTail); Interlocked.Increment(ref _count); }
/// <summary> /// Inserts an object at the top of the stack. /// </summary> /// <param name="item">the object to push onto the stack</param> public void Push(T item) { SingleLinkNode <T> newNode = new SingleLinkNode <T>(); newNode.Item = item; do { newNode.Next = _head.Next; } while (Interlocked.CompareExchange <SingleLinkNode <T> >(ref _head.Next, newNode, newNode.Next) != newNode.Next); }
/// <summary> /// Clears the queue. /// </summary> /// <remarks>This method is not thread-safe.</remarks> public void Clear() { SingleLinkNode <T> tempNode; SingleLinkNode <T> currentNode = _head; while (currentNode != null) { tempNode = currentNode; currentNode = currentNode.Next; tempNode.Item = default(T); tempNode.Next = null; } _head = new SingleLinkNode <T>(); _tail = _head; _count = 0; }
/// <summary> /// Returns an enumerator that iterates through the queue. /// </summary> /// <returns>an enumerator for the queue</returns> public IEnumerator <T> GetEnumerator() { SingleLinkNode <T> currentNode = _head; do { if (currentNode.Item == null) { yield break; } else { yield return(currentNode.Item); } }while ((currentNode = currentNode.Next) != null); yield break; }
/// <summary> /// Removes and returns the object at the beginning of the queue. /// </summary> /// <param name="item"> /// when the method returns, contains the object removed from the beginning of the queue, /// if the queue is not empty; otherwise it is the default value for the element type /// </param> /// <returns> /// true if an object from removed from the beginning of the queue; /// false if the queue is empty /// </returns> public bool TryDequeue(out T item) { item = default(T); SingleLinkNode <T> oldHead = null; bool haveAdvancedHead = false; while (!haveAdvancedHead) { oldHead = _head; SingleLinkNode <T> oldTail = _tail; SingleLinkNode <T> oldHeadNext = oldHead.Next; if (oldHead == _head) { if (oldHead == oldTail) { if (oldHeadNext == null) { return(false); } Interlocked.CompareExchange <SingleLinkNode <T> >(ref _tail, oldHeadNext, oldTail); } else { item = oldHeadNext.Item; haveAdvancedHead = Interlocked.CompareExchange <SingleLinkNode <T> >(ref _head, oldHeadNext, oldHead) == oldHead; } } } Interlocked.Decrement(ref _count); return(true); }
/// <summary> /// Default constructor. /// </summary> public LockfreeQueue() { _head = new SingleLinkNode <T>(); _tail = _head; }
/// <summary> /// Default constructors. /// </summary> public LockFreeStack() { _head = new SingleLinkNode <T>(); }