void InnerNext(InnerSubscriber inner, T item) { if (Volatile.Read(ref wip) == 0 && Interlocked.CompareExchange(ref wip, 1, 0) == 0) { long r = Volatile.Read(ref requested); long e = emitted; if (e != r) { actual.OnNext(item); emitted = e + 1; inner.Produced(limit); } else { var q = inner.GetOrCreateQueue(limit); q.Offer(item); } int w = Interlocked.Decrement(ref wip); if (w == 0) { return; } DrainLoop(w); } else { var q = inner.GetOrCreateQueue(limit); q.Offer(item); if (Interlocked.Increment(ref wip) != 1) { return; } DrainLoop(1); } }
void InnerNext(InnerSubscriber inner, R item) { if (Volatile.Read(ref wip) == 0 && Interlocked.CompareExchange(ref wip, 1, 0) == 0) { var q = Volatile.Read(ref inner.queue); bool offer = true; if (current == inner) { if (q == null || q.IsEmpty()) { var e = emitted; if (e != Volatile.Read(ref requested)) { actual.OnNext(item); emitted = e + 1; inner.RequestOne(); offer = false; } } } if (offer) { if (q == null) { q = inner.GetOrCreateQueue(); } q.Offer(item); } if (Interlocked.Decrement(ref wip) == 0) { return; } } else { var q = inner.GetOrCreateQueue(); q.Offer(item); if (Interlocked.Increment(ref wip) != 1) { return; } } DrainLoop(); }