Beispiel #1
0
        public void OnNext(T t)
        {
            var s    = capacityHint;
            var item = tail;

            var i = item.count;

            if (i == s)
            {
                var b = new PublisherCacheItem(s);
                b.array[0] = t;
                b.count    = 1;
                item.svNext(b);
                tail = b;
            }
            else
            {
                item.array[i] = t;
                item.svCount(i + 1);
            }

            foreach (var inner in Volatile.Read(ref subscribers))
            {
                inner.Drain();
            }
        }
Beispiel #2
0
 public PublisherCacheInner(ISubscriber <T> actual, PublisherCache <T> parent, int bufferSize, PublisherCacheItem h)
 {
     this.actual     = actual;
     this.parent     = parent;
     this.bufferSize = bufferSize;
     this.current    = h;
 }
Beispiel #3
0
        public PublisherCache(IPublisher <T> source, int capacityHint)
        {
            this.source       = source;
            this.capacityHint = capacityHint;

            PublisherCacheItem h = new PublisherCacheItem(capacityHint);

            head = h;
            tail = h;
        }
Beispiel #4
0
            internal void Drain()
            {
                if (!bp.Enter())
                {
                    return;
                }

                PublisherCache <T> p    = parent;
                ISubscriber <T>    a    = actual;
                PublisherCacheItem item = current;
                int c = offset;

                int  missed = 1;
                long r      = bp.Requested();
                long e      = 0L;

                for (;;)
                {
                    if (IsCancelled())
                    {
                        return;
                    }

                    if (CheckTerminated(p.IsDone(), item.lvCount() == c && item.lvNext() == null, a, p))
                    {
                        return;
                    }

                    while (r != e)
                    {
                        if (IsCancelled())
                        {
                            return;
                        }
                        bool d     = p.IsDone();
                        var  next  = item.lvNext();
                        var  f     = item.lvCount();
                        bool empty = f == c && next == null;

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

                        if (empty)
                        {
                            break;
                        }

                        if (f == c)
                        {
                            item = next;
                            c    = 0;
                        }

                        T v = item.array[c];

                        c++;
                    }

                    if (CheckTerminated(p.IsDone(), item.lvCount() == c && item.lvNext() == null, a, p))
                    {
                        return;
                    }

                    r = bp.Requested();

                    if (e == r)
                    {
                        current = item;
                        offset  = c;
                        r       = bp.Produced(e);
                        if (r != 0L)
                        {
                            e = 0L;
                            continue;
                        }
                    }

                    missed = bp.Leave(missed);
                    if (missed == 0)
                    {
                        break;
                    }
                }
            }
Beispiel #5
0
 internal void svNext(PublisherCacheItem next)
 {
     Volatile.Write(ref this.next, next);
 }