public IDisposable Connect(Action <IDisposable> onConnect = null) { for (; ;) { var subject = Volatile.Read(ref connection); if (subject == null) { subject = new CacheSubject <T>(); if (Interlocked.CompareExchange(ref connection, subject, null) != null) { continue; } } else { if (subject.HasException() || subject.HasCompleted() || subject.IsDisposed()) { Interlocked.CompareExchange(ref connection, null, subject); continue; } } var shouldConnect = subject.Prepare(); onConnect?.Invoke(subject); if (shouldConnect) { source.Subscribe(subject); } return(subject); } }
public void Dispose() { if (Interlocked.Exchange(ref downstream, null) != null) { parent.Remove(this); parent.manager.Drain(this); parent = null; } }
public void Subscribe(ISignalObserver <T> observer) { for (; ;) { var subject = Volatile.Read(ref connection); if (subject == null) { subject = new CacheSubject <T>(); if (Interlocked.CompareExchange(ref connection, subject, null) != null) { continue; } } subject.Subscribe(observer); break; } }
public CacheDisposable(ISignalObserver <T> downstream, CacheSubject <T> parent) { this.downstream = downstream; Volatile.Write(ref this.parent, parent); }