internal JoinSubscription(ISubscriber <T> actual, int n, int prefetch) { this.actual = actual; var a = new JoinInnerSubscriber[n]; for (int i = 0; i < n; i++) { a[i] = new JoinInnerSubscriber(this, prefetch); } this.subscribers = a; Volatile.Write(ref done, n); }
internal void InnerNext(JoinInnerSubscriber inner, T value) { if (QueueDrainHelper.TryEnter(ref wip)) { long r = Volatile.Read(ref requested); if (r != 0L) { actual.OnNext(value); if (r != long.MaxValue) { Interlocked.Decrement(ref requested); } inner.RequestOne(); } else { var q = inner.Queue(); if (!q.Offer(value)) { InnerError(BackpressureHelper.MissingBackpressureException("Queue full?!")); return; } } if (QueueDrainHelper.Leave(ref wip, 1) == 0) { return; } } else { var q = inner.Queue(); if (!q.Offer(value)) { InnerError(BackpressureHelper.MissingBackpressureException("Queue full?!")); return; } if (!QueueDrainHelper.Enter(ref wip)) { return; } } DrainLoop(); }