private void Remove(InnerHandler handler) { for (; ;) { var a = Volatile.Read(ref _inners); var n = a.Length; if (n == 0) { break; } var idx = Array.IndexOf(a, handler); if (idx < 0) { break; } InnerHandler[] b; if (n == 1) { b = Empty; } else { b = new InnerHandler[n - 1]; Array.Copy(a, 0, b, 0, idx); Array.Copy(a, idx + 1, b, idx, n - idx - 1); } if (Interlocked.CompareExchange(ref _inners, b, a) == a) { handler.Dispose(); break; } } }
private void NextHandler(Task <bool> t) { if (t.IsFaulted) { ExceptionHelper.AddException(ref _error, ExceptionHelper.Extract(t.Exception)); _done = true; if (TryDispose()) { Signal(); } } else if (t.Result) { IAsyncEnumerator <TResult> src; try { src = _mapper(_source.Current).GetAsyncEnumerator(); } catch (Exception ex) { ExceptionHelper.AddException(ref _error, ex); _done = true; Dispose(_source); Signal(); return; } if (TryDispose()) { Interlocked.Increment(ref _allDisposeWip); var inner = new InnerHandler(src, this); for (; ;) { var curr = Volatile.Read(ref _current); if (curr == DisposedInnerHandler) { inner.Dispose(); break; } if (Interlocked.CompareExchange(ref _current, inner, curr) == curr) { curr?.Dispose(); inner.MoveNext(); MoveNext(); return; } } } } else { _done = true; if (TryDispose()) { Signal(); } } }
protected override void Dispose(bool disposing) { base.Dispose(disposing); if (disposing && ownsHandler) { InnerHandler.Dispose(); } }
// ReSharper restore ExplicitCallerInfoArgument /// <summary> /// Releases the unmanaged resources used by the <see cref="T:System.Net.Http.DelegatingHandler" />, and optionally disposes of the managed resources. /// </summary> /// <param name="disposing">true to release both managed and unmanaged resources; false to releases only unmanaged resources.</param> protected override void Dispose(bool disposing) { if (disposing && Interlocked.CompareExchange(ref _disposeInner, 0, 1) == 1) { InnerHandler.Dispose(); } base.Dispose(disposing); }
private void CreateNewTransportHandler() { if (InnerHandler != null) { InnerHandler.Dispose(); InnerHandler = null; } // Ask the ContinuationFactory to attach the proper handler given the Context's ITransportSettings. InnerHandler = ContinuationFactory(Context, null); }
public override async Task OpenAsync(TimeoutHelper timeoutHelper) { try { if (Logging.IsEnabled) { Logging.Enter(this, timeoutHelper, $"{nameof(ProtocolRoutingDelegatingHandler)}.{nameof(OpenAsync)}"); } bool gain = await _handlerLock.WaitAsync(timeoutHelper.GetRemainingTime()).ConfigureAwait(false); if (!gain) { throw new TimeoutException("Timed out to acquire handler lock."); } SelectTransport(); try { CreateNewTransportIfNotReady(); await base.OpenAsync(timeoutHelper).ConfigureAwait(false); // since Dispose is not synced with _handlerLock, double check if disposed. if (_disposed) { InnerHandler?.Dispose(); ThrowIfDisposed(); } _transportSelectionComplete = true; } finally { _handlerLock.Release(); } } finally { if (Logging.IsEnabled) { Logging.Exit(this, timeoutHelper, $"{nameof(ProtocolRoutingDelegatingHandler)}.{nameof(OpenAsync)}"); } } }
public override async Task OpenAsync(CancellationToken cancellationToken) { try { if (Logging.IsEnabled) { Logging.Enter(this, cancellationToken, $"{nameof(ProtocolRoutingDelegatingHandler)}.{nameof(OpenAsync)}"); } cancellationToken.ThrowIfCancellationRequested(); await _handlerLock.WaitAsync(cancellationToken).ConfigureAwait(false); SelectTransport(); try { CreateNewTransportIfNotReady(); await base.OpenAsync(cancellationToken).ConfigureAwait(false); // since Dispose is not synced with _handlerLock, double check if disposed. if (_disposed) { InnerHandler?.Dispose(); ThrowIfDisposed(); } _transportSelectionComplete = true; } finally { _handlerLock.Release(); } } finally { if (Logging.IsEnabled) { Logging.Exit(this, cancellationToken, $"{nameof(ProtocolRoutingDelegatingHandler)}.{nameof(OpenAsync)}"); } } }
public override async Task OpenAsync(CancellationToken cancellationToken) { try { if (Logging.IsEnabled) { Logging.Enter(this, cancellationToken, $"{nameof(ProtocolRoutingDelegatingHandler)}.{nameof(OpenAsync)}"); } cancellationToken.ThrowIfCancellationRequested(); await _handlerLock.WaitAsync().ConfigureAwait(false); if (!_transportSelectionComplete) { // Try next protocol if we're still searching. ITransportSettings[] transportSettingsArray = this.Context.Get <ITransportSettings[]>(); Debug.Assert(transportSettingsArray != null); // Keep cycling through all transports until we find one that works. if (_nextTransportIndex >= transportSettingsArray.Length) { _nextTransportIndex = 0; } ITransportSettings transportSettings = transportSettingsArray[_nextTransportIndex]; Debug.Assert(transportSettings != null); if (Logging.IsEnabled) { Logging.Info( this, $"Trying {transportSettings?.GetTransportType()}", $"{nameof(ProtocolRoutingDelegatingHandler)}.{nameof(OpenAsync)}"); } // Configure the transportSettings for this context (Important! Within Context, 'ITransportSettings' != 'ITransportSettings[]'). Context.Set <ITransportSettings>(transportSettings); CreateNewTransportHandler(); _nextTransportIndex++; } try { CreateNewTransportIfNotReady(); await base.OpenAsync(cancellationToken).ConfigureAwait(false); // since Dispose is not synced with _handlerLock, double check if disposed. if (_disposed) { InnerHandler?.Dispose(); ThrowIfDisposed(); } _transportSelectionComplete = true; } finally { _handlerLock.Release(); } } finally { if (Logging.IsEnabled) { Logging.Exit(this, cancellationToken, $"{nameof(ProtocolRoutingDelegatingHandler)}.{nameof(OpenAsync)}"); } } }