Ejemplo n.º 1
0
            public async ValueTask <bool> Drain(ReplayEnumerator consumer)
            {
                for (; ;)
                {
                    var d     = _done;
                    var s     = _size;
                    var index = consumer.Index;

                    if (d && s == index)
                    {
                        if (_error != null)
                        {
                            throw _error;
                        }
                        return(false);
                    }

                    if (index != s)
                    {
                        consumer.Current = _values[index];
                        consumer.Index   = index + 1;
                        return(true);
                    }

                    await ResumeHelper.Await(ref consumer.Resume);

                    ResumeHelper.Clear(ref consumer.Resume);
                }
            }
Ejemplo n.º 2
0
        private void Remove(ReplayEnumerator inner)
        {
            for (; ;)
            {
                var a = Volatile.Read(ref _enumerators);
                var n = a.Length;
                if (n == 0)
                {
                    return;
                }

                var j = Array.IndexOf(a, inner);

                if (j < 0)
                {
                    return;
                }

                ReplayEnumerator[] b;
                if (n == 1)
                {
                    b = Empty;
                }
                else
                {
                    b = new ReplayEnumerator[n - 1];
                    Array.Copy(a, 0, b, 0, j);
                    Array.Copy(a, j + 1, b, j, n - j - 1);
                }
                if (Interlocked.CompareExchange(ref _enumerators, b, a) == a)
                {
                    return;
                }
            }
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Returns an <see cref="IAsyncEnumerator{T}"/> representing an active asynchronous sequence.
        /// </summary>
        /// <returns>The active asynchronous sequence to be consumed.</returns>
        public IAsyncEnumerator <T> GetAsyncEnumerator()
        {
            var en = new ReplayEnumerator(this);

            Add(en);
            return(en);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Returns an <see cref="IAsyncEnumerator{T}"/> representing an active asynchronous sequence.
        /// </summary>
        /// <returns>The active asynchronous sequence to be consumed.</returns>
        public IAsyncEnumerator <T> GetAsyncEnumerator(CancellationToken cancellationToken)
        {
            var en = new ReplayEnumerator(this);

            Add(en);
            // FIXME what about the registration???
            cancellationToken.Register(v => (v as ReplayEnumerator)?.Cancel(), en);

            return(en);
        }
Ejemplo n.º 5
0
 private void Add(ReplayEnumerator inner)
 {
     for (; ;)
     {
         var a = Volatile.Read(ref _enumerators);
         if (a == Terminated)
         {
             return;
         }
         var n = a.Length;
         var b = new ReplayEnumerator[n + 1];
         Array.Copy(a, 0, b, 0, n);
         b[n] = inner;
         if (Interlocked.CompareExchange(ref _enumerators, b, a) == a)
         {
             return;
         }
     }
 }