Пример #1
0
        void Signal(PublisherSwitchMapSubscriber sender, R value, bool done)
        {
            if (Volatile.Read(ref index) != sender.Index())
            {
                if (done)
                {
                    Exception e = sender.Error();

                    if (e != null)
                    {
                        RxAdvancedFlowPlugins.OnError(e);
                    }
                }
                return;
            }

            PublisherSwitchMapStruct s = new PublisherSwitchMapStruct();

            s.sender = sender;
            s.value  = value;
            s.done   = done;

            lock (this)
            {
                q.OfferRef(ref s);
            }

            if (done)
            {
                sender.SetDone();
            }

            Drain();
        }
Пример #2
0
        void Drain()
        {
            if (!bp.Enter())
            {
                return;
            }

            ISubscriber <R> a      = actual;
            int             missed = 1;

            for (;;)
            {
                long r = bp.Requested();
                long e = 0L;

                for (;;)
                {
                    PublisherSwitchMapStruct v;

                    bool empty = q.Peek(out v);

                    if (CheckTerminated(Volatile.Read(ref done), empty, a))
                    {
                        return;
                    }

                    if (empty)
                    {
                        if (e != 0L)
                        {
                            bp.Produced(e);
                        }
                        break;
                    }

                    PublisherSwitchMapSubscriber sender = v.sender;

                    if (Volatile.Read(ref index) == sender.Index())
                    {
                        if (v.done)
                        {
                            Exception ex = sender.Error();
                            if (ex != null)
                            {
                                Cancel();

                                q.Clear();

                                a.OnError(ex);
                                return;
                            }

                            q.Drop();
                        }
                        else
                        if (r != e)
                        {
                            a.OnNext(v.value);

                            q.Drop();
                            e++;
                        }
                        else
                        {
                            if (e != 0L)
                            {
                                bp.Produced(e);

                                sender.Request(e);
                            }
                            break;
                        }
                    }
                    else
                    {
                        q.Drop();
                    }
                }

                if (CheckTerminated(Volatile.Read(ref done), q.IsEmpty(), a))
                {
                    return;
                }

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

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