/// <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);
        }
예제 #2
0
        /// <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
                    };
                }
            }
        }
예제 #3
0
        /// <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);
        }
예제 #4
0
        /// <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);
        }