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(); }
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; } } }