示例#1
0
        public int Drain(Action <T> act, int limit)
        {
            long consumerIndex;
            long pIndex;

            for (var i = 0; i < limit; i++)
            {
                do
                {
                    pIndex        = this.producerIndex.VolatileRead();
                    consumerIndex = this.consumerIndex.VolatileRead();
                    if (consumerIndex >= pIndex)
                    {
                        return(i);
                    }
                } while (!buffer.HasValue(consumerIndex) ||
                         !this.consumerIndex.CompareExchange(
                             consumerIndex + 1,
                             consumerIndex));

                var success = this.buffer.TryGet(consumerIndex, out T value);
                Debug.Assert(success, "Did not successfully get the value in a drain");
                act(value);
                success = this.buffer.Clear(consumerIndex);
                Debug.Assert(success, "Unable to clear the value on a drain");
            }
            return(limit);
        }
示例#2
0
        public bool TryPoll(out T value)
        {
            long pIndex;
            long consumerIndex;

            do
            {
                pIndex        = this.producerIndex.VolatileRead();
                consumerIndex = this.consumerIndex.VolatileRead();
                if (consumerIndex >= pIndex)
                {
                    value = default(T);
                    return(false);
                }
            } while (!this.buffer.HasValue(consumerIndex) || !this.consumerIndex.CompareExchange(consumerIndex + 1, consumerIndex));

            var get = this.buffer.TryGet(consumerIndex, out value);

            this.buffer.Clear(consumerIndex);
            Debug.Assert(get, $"Failed to get the value. {consumerIndex}");
            return(true);
        }
示例#3
0
        public bool Offer(T value)
        {
            var  capacity = this.buffer.Length;
            long pIndex;
            long consumerIndex;

            do
            {
                pIndex        = this.producerIndex.VolatileRead();
                consumerIndex = this.consumerIndex.VolatileRead();
                if (pIndex - capacity >= consumerIndex)
                {
                    return(false);
                }
            } while (!this.buffer.IsEmpty(pIndex) || // Need to go around again if a value is still at that position.
                     !this.producerIndex.CompareExchange(pIndex + 1, pIndex));

            var set = this.buffer.Set(pIndex, value);

            Debug.Assert(set, $"Did not find an open position correctly {pIndex}");
            return(true);
        }