Beispiel #1
0
            internal void Subscribe(ISubscriber <T> s)
            {
                PublisherReplayInner inner = new PublisherReplayInner(s, this);

                s.OnSubscribe(inner);

                Add(inner);

                if (inner.IsCancelled())
                {
                    Remove(inner);
                }
                else
                {
                    Drain(inner);
                }
            }
Beispiel #2
0
            bool CheckTerminated(bool d, bool empty, PublisherReplayInner inner, ISubscriber <T> a)
            {
                if (inner.IsCancelled())
                {
                    inner.current = null;
                    return(true);
                }

                if (d && empty)
                {
                    Exception e = error;
                    if (e != null)
                    {
                        a.OnError(e);
                    }
                    else
                    {
                        a.OnComplete();
                    }
                    return(true);
                }
                return(false);
            }
Beispiel #3
0
 void Remove(PublisherReplayInner inner)
 {
     ProcessorHelper.Remove(ref subscribers, inner, Terminated, Empty);
 }
Beispiel #4
0
 void Add(PublisherReplayInner inner)
 {
     ProcessorHelper.Add(ref subscribers, inner, Terminated);
 }
Beispiel #5
0
            void Drain(PublisherReplayInner inner)
            {
                if (!inner.Enter())
                {
                    return;
                }

                int missed = 1;

                ISubscriber <T> a = inner.actual;

                for (;;)
                {
                    bool d = Volatile.Read(ref done);

                    Node current = inner.current;
                    int  offset  = inner.offset;
                    T[]  array   = current.array;

                    bool empty = current.LvNext() == null && current.LvCount() == offset;

                    if (CheckTerminated(d, empty, inner, a))
                    {
                        return;
                    }

                    long r = inner.Requested();
                    long e = 0L;

                    while (e != r)
                    {
                        d = Volatile.Read(ref done);

                        current = inner.current;
                        offset  = inner.offset;

                        Node next = current.LvNext();
                        int  c    = current.LvCount();

                        empty = next == null && c == offset;

                        if (CheckTerminated(d, empty, inner, a))
                        {
                            return;
                        }

                        if (empty)
                        {
                            break;
                        }

                        if (c == offset && next != null)
                        {
                            current = next;
                            array   = next.array;
                            offset  = 0;
                        }

                        T t = array[offset];

                        a.OnNext(t);

                        offset++;
                        e++;
                    }

                    if (e == r)
                    {
                        d = Volatile.Read(ref done);

                        current = inner.current;
                        offset  = inner.offset;

                        empty = current.LvNext() == null && current.LvCount() == offset;

                        if (CheckTerminated(d, empty, inner, a))
                        {
                            return;
                        }
                    }

                    if (e != 0)
                    {
                        inner.Produced(e);
                    }

                    inner.current = current;
                    inner.offset  = offset;

                    missed = inner.Leave(missed);
                    if (missed == 0)
                    {
                        break;
                    }
                }
            }