public void Subscribe(ISignalObserver <T> observer)
        {
            ValidationHelper.RequireNonNull(observer, nameof(observer));

            var errorSignals = new PublishSubject <Exception>();
            var redo         = default(IObservableSource <U>);

            try
            {
                redo = ValidationHelper.RequireNonNullRef(handler(errorSignals), "The handler returned a null IObservableSource");
            }
            catch (Exception ex)
            {
                DisposableHelper.Error(observer, ex);
                return;
            }

            var parent = new MainObserver(observer, source, new SerializedSignalObserver <Exception>(errorSignals));

            observer.OnSubscribe(parent);

            redo.Subscribe(parent.handlerObserver);

            parent.HandlerNext();
        }
        public IDisposable Connect(Action <IDisposable> onConnect = null)
        {
            for (; ;)
            {
                var subject = Volatile.Read(ref connection);
                if (subject == null)
                {
                    subject = new PublishSubject <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 = null;
     }
 }
        public void Subscribe(ISignalObserver <T> observer)
        {
            for (; ;)
            {
                var subject = Volatile.Read(ref connection);
                if (subject == null)
                {
                    subject = new PublishSubject <T>();
                    if (Interlocked.CompareExchange(ref connection, subject, null) != null)
                    {
                        continue;
                    }
                }

                subject.Subscribe(observer);

                break;
            }
        }
 public PublishDisposable(ISignalObserver <T> downstream, PublishSubject <T> parent)
 {
     this.downstream = downstream;
     Volatile.Write(ref this.parent, parent);
 }