Пример #1
0
 internal static void Clear <T>(ISimpleQueue <T> q)
 {
     while (q.Poll(out T item) && !q.IsEmpty())
     {
         ;
     }
 }
Пример #2
0
        internal static void QueueDrainFused <T>(IFlowableSubscriber <T> a,
                                                 ref int wip, ISimpleQueue <T> q, ref bool cancelled, ref bool done, ref Exception error)
        {
            if (Interlocked.Increment(ref wip) != 1)
            {
                return;
            }

            int missed = 1;

            for (;;)
            {
                if (Volatile.Read(ref cancelled))
                {
                    q.Clear();
                    return;
                }
                bool d     = Volatile.Read(ref done);
                bool empty = q.IsEmpty();

                if (!empty)
                {
                    a.OnNext(default(T));
                }

                if (d)
                {
                    var ex = error;
                    if (ex == null)
                    {
                        a.OnComplete();
                    }
                    else
                    {
                        a.OnError(ex);
                    }
                }

                int w = Volatile.Read(ref wip);
                if (w == missed)
                {
                    missed = Interlocked.Add(ref wip, -missed);
                    if (missed == 0)
                    {
                        break;
                    }
                }
                else
                {
                    missed = w;
                }
            }
        }
Пример #3
0
        static void PostCompleteMultiDrain <T>(IFlowableSubscriber <T> actual, ref long requested, ISimpleQueue <T> q, ref bool cancelled)
        {
            long r = Volatile.Read(ref requested);
            long e = long.MinValue;

            for (;;)
            {
                while (e != r)
                {
                    if (Volatile.Read(ref cancelled))
                    {
                        return;
                    }

                    bool empty = !q.Poll(out T v);

                    if (empty)
                    {
                        actual.OnComplete();
                        return;
                    }

                    actual.OnNext(v);

                    e++;
                }

                if (e == r)
                {
                    if (Volatile.Read(ref cancelled))
                    {
                        return;
                    }
                    if (q.IsEmpty())
                    {
                        actual.OnComplete();
                        return;
                    }
                }

                r = Volatile.Read(ref requested);
                if (r == e)
                {
                    r = Interlocked.Add(ref requested, -(e & long.MaxValue));

                    if (r == long.MinValue)
                    {
                        break;
                    }
                    e = long.MinValue;
                }
            }
        }
Пример #4
0
            void DrainFused()
            {
                int missed = 1;

                IFlowableSubscriber <T> a = actual;
                ISimpleQueue <T>        q = queue;

                for (;;)
                {
                    if (Volatile.Read(ref cancelled))
                    {
                        q.Clear();
                        return;
                    }

                    bool d     = Volatile.Read(ref done);
                    bool empty = q.IsEmpty();

                    if (!empty)
                    {
                        a.OnNext(default(T));
                    }

                    if (d)
                    {
                        Exception ex = error;
                        if (ex != null)
                        {
                            a.OnError(ex);
                        }
                        else
                        {
                            a.OnComplete();
                        }
                        return;
                    }

                    int w = Volatile.Read(ref wip);
                    if (w == missed)
                    {
                        missed = Interlocked.Add(ref wip, -missed);
                        if (missed == 0)
                        {
                            break;
                        }
                    }
                    else
                    {
                        missed = w;
                    }
                }
            }
 public bool IsEmpty()
 {
     return(queue.IsEmpty());
 }
Пример #6
0
            void DrainLoop()
            {
                IFlowableSubscriber <R> a = actual;
                int  missed = 1;
                long e      = emitted;

                for (;;)
                {
                    if (Volatile.Read(ref cancelled) != 0)
                    {
                        return;
                    }
                    bool again = false;
                    bool d     = Volatile.Read(ref done);
                    FlatMapInnerSubscriber[] s = Volatile.Read(ref subscribers);
                    int n = s.Length;

                    if (d && n == 0)
                    {
                        Exception ex = ExceptionHelper.Terminate(ref error);
                        if (ex == null)
                        {
                            a.OnComplete();
                        }
                        else
                        {
                            a.OnError(ex);
                        }
                        return;
                    }

                    long r = Volatile.Read(ref requested);

                    if (n != 0)
                    {
                        for (int i = 0; i < n; i++)
                        {
                            if (Volatile.Read(ref cancelled) != 0)
                            {
                                return;
                            }
                            if (r == e)
                            {
                                break;
                            }

                            var inner = s[i];

                            bool             innerDone  = Volatile.Read(ref inner.done);
                            ISimpleQueue <R> q          = Volatile.Read(ref inner.queue);
                            bool             innerEmpty = q == null || q.IsEmpty();

                            if (innerDone && innerEmpty)
                            {
                                Remove(inner);
                                upstream.Request(1);
                                again = true;
                            }
                            else
                            if (!innerEmpty)
                            {
                                while (e != r)
                                {
                                    if (Volatile.Read(ref cancelled) != 0)
                                    {
                                        return;
                                    }
                                    innerDone  = Volatile.Read(ref inner.done);
                                    innerEmpty = !q.Poll(out R item);

                                    if (innerDone && innerEmpty)
                                    {
                                        Remove(inner);
                                        upstream.Request(1);
                                        again = true;
                                        break;
                                    }

                                    if (innerEmpty)
                                    {
                                        break;
                                    }

                                    a.OnNext(item);

                                    e++;
                                    inner.Request(1);
                                }

                                if (e == r)
                                {
                                    if (Volatile.Read(ref cancelled) != 0)
                                    {
                                        return;
                                    }
                                    innerDone  = Volatile.Read(ref inner.done);
                                    innerEmpty = q.IsEmpty();
                                    if (innerDone && innerEmpty)
                                    {
                                        Remove(inner);
                                        upstream.Request(1);
                                        again = true;
                                    }
                                }
                            }
                        }
                    }

                    if (e == r)
                    {
                        d = Volatile.Read(ref done);
                        s = Volatile.Read(ref subscribers);
                        n = s.Length;

                        if (d && n == 0)
                        {
                            Exception ex = ExceptionHelper.Terminate(ref error);
                            if (ex == null)
                            {
                                a.OnComplete();
                            }
                            else
                            {
                                a.OnError(ex);
                            }
                            return;
                        }
                    }

                    if (again)
                    {
                        continue;
                    }
                    int w = Volatile.Read(ref wip);
                    if (w == missed)
                    {
                        emitted = e;
                        missed  = Interlocked.Add(ref wip, -missed);
                        if (missed == 0)
                        {
                            break;
                        }
                    }
                    else
                    {
                        missed = w;
                    }
                }
            }
 public bool IsEmpty()
 {
     return(windows.IsEmpty());
 }
Пример #8
0
 public bool IsEmpty()
 {
     return(current == null && queue.IsEmpty());
 }
Пример #9
0
            void DrainAsync()
            {
                int  missed = 1;
                long e      = emitted;
                int  f      = consumed;
                int  lim    = limit;
                IFlowableSubscriber <T> a = actual;
                ISimpleQueue <T>        q = queue;

                for (;;)
                {
                    long r = Volatile.Read(ref requested);

                    while (e != r)
                    {
                        if (Volatile.Read(ref cancelled))
                        {
                            q.Clear();
                            return;
                        }

                        bool d     = Volatile.Read(ref done);
                        bool empty = !q.Poll(out T item);

                        if (d && empty)
                        {
                            Exception ex = error;
                            if (ex != null)
                            {
                                a.OnError(ex);
                            }
                            else
                            {
                                a.OnComplete();
                            }
                            return;
                        }

                        if (empty)
                        {
                            break;
                        }

                        a.OnNext(item);

                        e++;

                        if (++f == lim)
                        {
                            f = 0;
                            upstream.Request(lim);
                        }
                    }

                    if (e == r)
                    {
                        if (Volatile.Read(ref cancelled))
                        {
                            q.Clear();
                            return;
                        }

                        bool d     = Volatile.Read(ref done);
                        bool empty = q.IsEmpty();

                        if (d && empty)
                        {
                            Exception ex = error;
                            if (ex != null)
                            {
                                a.OnError(ex);
                            }
                            else
                            {
                                a.OnComplete();
                            }
                            return;
                        }
                    }

                    int w = Volatile.Read(ref wip);
                    if (w == missed)
                    {
                        emitted  = e;
                        consumed = f;
                        missed   = Interlocked.Add(ref wip, -missed);
                        if (missed == 0)
                        {
                            break;
                        }
                    }
                    else
                    {
                        missed = w;
                    }
                }
            }
Пример #10
0
        internal static void QueueDrain <T>(IFlowableSubscriber <T> a,
                                            ref int wip, ISimpleQueue <T> q,
                                            ref long requested, ref long emitted, ref bool cancelled, ref bool done, ref Exception error)
        {
            if (Interlocked.Increment(ref wip) != 1)
            {
                return;
            }

            int missed = 1;
            var e      = emitted;

            for (;;)
            {
                long r = Volatile.Read(ref requested);

                while (e != r)
                {
                    if (Volatile.Read(ref cancelled))
                    {
                        q.Clear();
                        return;
                    }

                    bool d     = Volatile.Read(ref done);
                    bool empty = !q.Poll(out var item);

                    if (d && empty)
                    {
                        var ex = error;
                        if (ex == null)
                        {
                            a.OnComplete();
                        }
                        else
                        {
                            a.OnError(ex);
                        }
                        return;
                    }

                    if (empty)
                    {
                        break;
                    }

                    a.OnNext(item);

                    e++;
                }

                if (e == r)
                {
                    if (Volatile.Read(ref cancelled))
                    {
                        q.Clear();
                        return;
                    }

                    bool d     = Volatile.Read(ref done);
                    bool empty = q.IsEmpty();

                    if (d && empty)
                    {
                        var ex = error;
                        if (ex == null)
                        {
                            a.OnComplete();
                        }
                        else
                        {
                            a.OnError(ex);
                        }
                        return;
                    }
                }

                int w = Volatile.Read(ref wip);
                if (w == missed)
                {
                    emitted = e;
                    missed  = Interlocked.Add(ref wip, -missed);
                    if (missed == 0)
                    {
                        break;
                    }
                }
                else
                {
                    missed = w;
                }
            }
        }