/// <summary> /// Takes the next item from the pipeline, or blocks until an item /// is recieved. /// </summary> /// <returns>The next item.</returns> public T Take(out bool retrieved) { if (this.m_OutputThread != Thread.CurrentThread.ManagedThreadId) { throw new InvalidOperationException("Only the output thread may retrieve items from TaskPipeline."); } // Wait until there is an item to take. var spin = new SpinWait(); while (this.m_Head == null) { spin.SpinOnce(); } // Return the item and exchange the current head with // the next item, all in an atomic operation. var head = m_Head; retry: var next = head.Next; if (Interlocked.CompareExchange(ref head.Next, TaskPipelineEntry <T> .Sentinel, next) != next) { goto retry; } this.m_Head = next; retrieved = true; return(head.Value); }
/// <summary> /// Puts an item into the queue to be processed. /// </summary> /// <param name="value">Value.</param> public void Put(T value) { if (this.m_InputThread != Thread.CurrentThread.ManagedThreadId) { throw new InvalidOperationException("Only the input thread may place items into TaskPipeline."); } lock (this) { var head = this.m_Head; while (head != null && head.Next != null) { head = head.Next; } if (head == null) { m_Head = new TaskPipelineEntry <T> { Value = value }; } else { head.Next = new TaskPipelineEntry <T> { Value = value }; } } }
/// <summary> /// Takes the next item from the pipeline, or blocks until an item /// is recieved. /// </summary> /// <returns>The next item.</returns> public T Take() { if (this.m_OutputThread != Thread.CurrentThread.ManagedThreadId) { throw new InvalidOperationException("Only the output thread may retrieve items from TaskPipeline."); } // Return if no value. var spin = new SpinWait(); while (this.m_Head == null) { spin.SpinOnce(); } T value; lock (this) { value = m_Head.Value; m_Head = m_Head.Next; } return(value); }
/// <summary> /// Takes the next item from the pipeline, or blocks until an item /// is recieved. /// </summary> /// <returns>The next item.</returns> public T Take(out bool retrieved) { if (this.m_OutputThread != Thread.CurrentThread.ManagedThreadId) { throw new InvalidOperationException("Only the output thread may retrieve items from TaskPipeline."); } // Return if no value. if (this.m_Head == null) { retrieved = false; return(default(T)); } T value; lock (this) { value = m_Head.Value; m_Head = m_Head.Next; } retrieved = true; return(value); }