public void Run() { var doConnect = false; var conn = default(RefConnection); lock (_parent._gate) { // get the active connection state conn = _parent._connection; // if null, a new connection should be established if (conn == null) { conn = new RefConnection(); // make it the active one _parent._connection = conn; } // this is the first observer, then connect doConnect = conn._count++ == 0; // save the current connection for this observer _targetConnection = conn; } // subscribe to the source first Run(_parent._source); // then connect the source if necessary if (doConnect && !Disposable.GetIsDisposed(ref conn._disposable)) { // this makes sure if the connection ends synchronously // only the currently known connection is affected // and a connection from a concurrent reconnection won't // interfere Disposable.SetSingle(ref conn._disposable, _parent._source.Connect()); } }
protected override void Dispose(bool disposing) { base.Dispose(disposing); if (disposing) { // get and forget the saved connection var targetConnection = _targetConnection; _targetConnection = null; lock (_parent._gate) { // if the current connection is no longer the saved connection // or the counter hasn't reached zero yet if (targetConnection != _parent._connection || --targetConnection._count != 0) { // nothing to do. return; } // forget the current connection _parent._connection = null; } // disconnect Disposable.TryDispose(ref targetConnection._disposable); } }
public void Run() { bool doConnect; RefConnection?conn; lock (_parent._gate) { // get the active connection state conn = _parent._connection; // if null, a new connection should be established if (conn == null) { conn = new RefConnection(); // make it the active one _parent._connection = conn; } // this is the first observer, then connect doConnect = ++conn._count == _parent._minObservers; // save the current connection for this observer _targetConnection = conn; } // subscribe to the source first Run(_parent._source); // then connect the source if necessary if (doConnect && !conn._disposable.IsDisposed) { // this makes sure if the connection ends synchronously // only the currently known connection is affected // and a connection from a concurrent reconnection won't // interfere conn._disposable.Disposable = _parent._source.Connect(); } }