| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101 | 
							- // Licensed to the .NET Foundation under one or more agreements.
 
- // The .NET Foundation licenses this file to you under the MIT License.
 
- // See the LICENSE file in the project root for more information. 
 
- using System.Reactive.Threading;
 
- using System.Threading;
 
- using System.Threading.Tasks;
 
- namespace System.Reactive.Disposables
 
- {
 
-     public sealed class RefCountAsyncDisposable : IAsyncDisposable
 
-     {
 
-         private readonly IAsyncGate _gate = AsyncGate.Create();
 
-         private IAsyncDisposable _disposable;
 
-         private bool _primaryDisposed;
 
-         private int _count;
 
-         public RefCountAsyncDisposable(IAsyncDisposable disposable)
 
-         {
 
-             _disposable = disposable ?? throw new ArgumentNullException(nameof(disposable));
 
-             _primaryDisposed = false;
 
-             _count = 0;
 
-         }
 
-         public async ValueTask<IAsyncDisposable> GetDisposableAsync()
 
-         {
 
-             using (await _gate.LockAsync().ConfigureAwait(false))
 
-             {
 
-                 if (_disposable == null)
 
-                 {
 
-                     return AsyncDisposable.Nop;
 
-                 }
 
-                 else
 
-                 {
 
-                     _count++;
 
-                     return new Inner(this);
 
-                 }
 
-             }
 
-         }
 
-         public async ValueTask DisposeAsync()
 
-         {
 
-             var disposable = default(IAsyncDisposable);
 
-             using (await _gate.LockAsync().ConfigureAwait(false))
 
-             {
 
-                 if (_disposable != null && !_primaryDisposed)
 
-                 {
 
-                     _primaryDisposed = true;
 
-                     if (_count == 0)
 
-                     {
 
-                         disposable = _disposable;
 
-                         _disposable = null;
 
-                     }
 
-                 }
 
-             }
 
-             if (disposable != null)
 
-             {
 
-                 await disposable.DisposeAsync().ConfigureAwait(false);
 
-             }
 
-         }
 
-         private async ValueTask ReleaseAsync()
 
-         {
 
-             var disposable = default(IAsyncDisposable);
 
-             using (await _gate.LockAsync().ConfigureAwait(false))
 
-             {
 
-                 if (_disposable != null)
 
-                 {
 
-                     _count--;
 
-                     if (_primaryDisposed && _count == 0)
 
-                     {
 
-                         disposable = _disposable;
 
-                         _disposable = null;
 
-                     }
 
-                 }
 
-             }
 
-             if (disposable != null)
 
-             {
 
-                 await disposable.DisposeAsync().ConfigureAwait(false);
 
-             }
 
-         }
 
-         private sealed class Inner : IAsyncDisposable
 
-         {
 
-             private RefCountAsyncDisposable _parent;
 
-             public Inner(RefCountAsyncDisposable parent)
 
-             {
 
-                 _parent = parent;
 
-             }
 
-             public ValueTask DisposeAsync() => Interlocked.Exchange(ref _parent, null)?.ReleaseAsync() ?? default;
 
-         }
 
-     }
 
- }
 
 
  |