public virtual void OnSubscribe(IDisposable d) { this.upstream = d; if (d is IFuseableDisposable <T> f) { this.queue = f; } downstream.OnSubscribe(this); }
/// <summary> /// Called at most once with the upstream's IDisposable instance. /// Further calls will dispose the IDisposable provided. /// </summary> /// <param name="d">The upstream's IDisposable instance.</param> public virtual void OnSubscribe(IDisposable d) { if (Interlocked.CompareExchange(ref this.upstream, d, null) != null) { d?.Dispose(); } else { if (fusionRequested > FusionSupport.None) { if (d is IFuseableDisposable <T> fd) { queue = fd; fusionEstablished = fd.RequestFusion(fusionRequested); if (fusionEstablished == FusionSupport.Sync) { for (; ;) { if (IsDisposed()) { break; } var v = default(T); var success = false; try { v = queue.TryPoll(out success); } catch (Exception ex) { Dispose(); OnError(ex); break; } if (!success) { OnCompleted(); break; } items.Add(v); Volatile.Write(ref itemCount, items.Count); } } } } } }
public void OnSubscribe(IDisposable d) { upstream = d as IFuseableDisposable <T>; if (upstream != null) { try { var m = upstream.RequestFusion(boundary ? FusionSupport.AnyBoundary : FusionSupport.Any); if (m != FusionSupport.None) { upstream.IsEmpty(); upstream.TryPoll(out var _); upstream.Clear(); upstream.IsEmpty(); upstream.TryPoll(out var _); try { upstream.TryOffer(default(T)); } catch (InvalidOperationException) { // expected } } } catch (Exception ex) { error = ex; } } else { error = new Exception("Upstream not fuseable"); } }