public void OnNext(T element) { if (Volatile.Read(ref done)) { return; } IPublisher <R> p; try { p = mapper(element); if (p == null) { throw new NullReferenceException("The mapper returned a null IPublisher"); } } catch (Exception ex) { upstream.Cancel(); OnError(ex); return; } FlatMapInnerSubscriber inner = new FlatMapInnerSubscriber(this, bufferSize); if (Add(inner)) { p.Subscribe(inner); } }
internal void InnerNext(FlatMapInnerSubscriber inner, R item) { if (Volatile.Read(ref wip) == 0 && Interlocked.CompareExchange(ref wip, 1, 0) == 0) { long e = emitted; if (Volatile.Read(ref requested) != e) { actual.OnNext(item); emitted = e + 1; inner.Request(1); } else { ISimpleQueue <R> q = inner.GetOrCreateQueue(); q.Offer(item); } if (Interlocked.Decrement(ref wip) == 0) { return; } } else { ISimpleQueue <R> q = inner.GetOrCreateQueue(); q.Offer(item); if (Interlocked.Increment(ref wip) != 1) { return; } } DrainLoop(); }
public void OnNext(T t) { if (lvDone()) { return; } IPublisher <R> p; try { p = mapper(t); } catch (Exception ex) { ExceptionHelper.ThrowIfFatal(ex); s.Cancel(); OnError(ex); return; } if (p == null) { s.Cancel(); OnError(new NullReferenceException("The mapper produced a null IPublisher")); } else if (p == PublisherEmpty <R> .Instance) { ScalarConsumed(); } else if (p is ICallable <R> ) { R scalar; try { scalar = (p as ICallable <R>).Value; } catch (Exception ex) { ExceptionHelper.ThrowIfFatal(ex); s.Cancel(); OnError(ex); return; } TryEmitScalar(scalar); } else { var inner = new FlatMapInnerSubscriber(this, prefetch); if (tracker.Add(inner)) { p.Subscribe(inner); } } }
internal void InnerError(FlatMapInnerSubscriber sender, Exception ex) { if (ExceptionHelper.AddError(ref error, ex)) { if (!delayErrors) { CancelAll(); } sender.svDone(); Drain(); } else { ExceptionHelper.OnErrorDropped(ex); } }
internal void InnerError(FlatMapInnerSubscriber inner, Exception ex) { ExceptionHelper.AddException(ref error, ex); if (!delayError) { if (!Volatile.Read(ref done)) { Volatile.Write(ref done, true); upstream.Cancel(); CancelAll(); } } Volatile.Write(ref inner.done, true); Drain(); }
internal void InnerNext(FlatMapInnerSubscriber sender, R value) { if (sender.IsAsyncFused()) { Drain(); return; } if (QueueDrainHelper.TryEnter(ref wip)) { long r = Volatile.Read(ref requested); if (r != 0) { actual.OnNext(value); if (r != long.MaxValue) { Interlocked.Decrement(ref requested); } sender.RequestOne(); } else { var q = sender.GetOrCreateQueue(); q.Offer(value); } if (Interlocked.Decrement(ref wip) == 0) { return; } } else { var q = sender.GetOrCreateQueue(); q.Offer(value); if (Interlocked.Increment(ref wip) != 1) { return; } } DrainLoop(); }
bool Add(FlatMapInnerSubscriber inner) { for (;;) { var a = Volatile.Read(ref subscribers); if (a == TERMINATED) { return(false); } int n = a.Length; var b = new FlatMapInnerSubscriber[n + 1]; Array.Copy(a, 0, b, 0, n); b[n] = inner; if (Interlocked.CompareExchange(ref subscribers, b, a) == a) { return(true); } } }
void Remove(FlatMapInnerSubscriber inner) { for (;;) { var a = Volatile.Read(ref subscribers); int n = a.Length; if (n == 0) { break; } int j = -1; for (int i = 0; i < n; i++) { if (a[i] == inner) { j = i; break; } } if (j < 0) { break; } FlatMapInnerSubscriber[] b; if (n == 1) { b = EMPTY; } else { b = new FlatMapInnerSubscriber[n - 1]; Array.Copy(a, 0, b, 0, j); Array.Copy(a, j + 1, b, j, n - j - 1); } if (Interlocked.CompareExchange(ref subscribers, b, a) == a) { break; } } }
internal void InnerComplete(FlatMapInnerSubscriber inner) { Volatile.Write(ref inner.done, true); Drain(); }
internal void InnerError(FlatMapInnerSubscriber inner, Exception ex) { ExceptionHelper.AddException(ref error, ex); Volatile.Write(ref inner.done, true); Drain(); }
internal void InnerComplete(FlatMapInnerSubscriber sender) { Drain(); }