public static Task <byte[]> ReadAllBytesAsync(string path, CancellationToken cancellationToken = default(CancellationToken)) { if (cancellationToken.IsCancellationRequested) { return(Task.FromCanceled <byte[]>(cancellationToken)); } // SequentialScan is a perf hint that requires extra sys-call on non-Windows OSes. FileOptions options = FileOptions.Asynchronous | (OperatingSystem.IsWindows() ? FileOptions.SequentialScan : FileOptions.None); SafeFileHandle sfh = OpenHandle(path, FileMode.Open, FileAccess.Read, FileShare.Read, options); long fileLength = 0L; if (sfh.CanSeek && (fileLength = sfh.GetFileLength()) > Array.MaxLength) { sfh.Dispose(); return(Task.FromException <byte[]>(ExceptionDispatchInfo.SetCurrentStackTrace(new IOException(SR.IO_FileTooLong2GB)))); } #if DEBUG fileLength = 0; // improve the test coverage for InternalReadAllBytesUnknownLengthAsync #endif return(fileLength > 0 ? InternalReadAllBytesAsync(sfh, (int)fileLength, cancellationToken) : InternalReadAllBytesUnknownLengthAsync(sfh, cancellationToken)); }
protected override ValueTask CloseAsyncCore(ConnectionCloseMethod method, CancellationToken cancellationToken) { if (cancellationToken.IsCancellationRequested) { return(ValueTask.FromCanceled(cancellationToken)); } try { if (method != ConnectionCloseMethod.GracefulShutdown) { // Dispose must be called first in order to cause a connection reset, // as NetworkStream.Dispose() will call Shutdown(Both). _socket.Dispose(); } // Since CreatePipe() calls CreateStream(), so _stream should be present even in the pipe case: _stream?.Dispose(); } catch (SocketException socketException) { return(ValueTask.FromException(ExceptionDispatchInfo.SetCurrentStackTrace(socketException))); } catch (Exception ex) { return(ValueTask.FromException(ex)); } return(default);
/// <inheritdoc/> public override ValueTask <ValueHttpRequest?> CreateNewRequestAsync(HttpPrimitiveVersion version, HttpVersionPolicy versionPolicy, CancellationToken cancellationToken = default) { if (_writeBuffer.ActiveLength != 0 || _responseContentBytesRemaining != 0) { return(ValueTask.FromException <ValueHttpRequest?>(ExceptionDispatchInfo.SetCurrentStackTrace(new Exception("Unable to create request stream with a request already pending.")))); } if (version.Major != 1) { if (versionPolicy == HttpVersionPolicy.RequestVersionOrLower) { version = HttpPrimitiveVersion.Version11; } return(ValueTask.FromException <ValueHttpRequest?>(ExceptionDispatchInfo.SetCurrentStackTrace(new Exception($"Unable to create request for HTTP/{version.Major}.{version.Minor} with a {nameof(Http1Connection)}.")))); } _writeState = WriteState.Unstarted; _requestIsChunked = true; _responseHasContentLength = false; _responseIsChunked = false; _readingFirstResponseChunk = false; _readFunc = s_ReadResponse; if (Interlocked.Exchange(ref _request, null) is Http1Request request) { request.Init(this, version); } else { request = new Http1Request(this, version); } return(new ValueTask <ValueHttpRequest?>(request.GetValueRequest())); }
private void CancelWaiter(CancellationToken cancellationToken) { if (Interlocked.Exchange(ref _hasWaiter, 0) == 1) { _waitSource.SetException(ExceptionDispatchInfo.SetCurrentStackTrace(new OperationCanceledException(cancellationToken))); } }
private static uint HandleEventShutdownComplete(State state, ref ConnectionEvent connectionEvent) { // This is the final event on the connection, so free the GCHandle used by the event callback. state.StateGCHandle.Free(); state.Connection = null; state.ShutdownTcs.SetResult(MsQuicStatusCodes.Success); // Stop accepting new streams. state.AcceptQueue.Writer.TryComplete(); // Stop notifying about available streams. TaskCompletionSource?unidirectionalTcs = null; TaskCompletionSource?bidirectionalTcs = null; lock (state) { unidirectionalTcs = state.NewUnidirectionalStreamsAvailable; bidirectionalTcs = state.NewBidirectionalStreamsAvailable; state.NewUnidirectionalStreamsAvailable = null; state.NewBidirectionalStreamsAvailable = null; } if (unidirectionalTcs is not null) { unidirectionalTcs.SetException(ExceptionDispatchInfo.SetCurrentStackTrace(new QuicOperationAbortedException())); } if (bidirectionalTcs is not null) { bidirectionalTcs.SetException(ExceptionDispatchInfo.SetCurrentStackTrace(new QuicOperationAbortedException())); } return(MsQuicStatusCodes.Success); }
protected override ValueTask CloseAsyncCore(ConnectionCloseMethod method, CancellationToken cancellationToken) { if (cancellationToken.IsCancellationRequested) { return(ValueTask.FromCanceled(cancellationToken)); } try { if (method != ConnectionCloseMethod.GracefulShutdown) { // Dispose must be called first in order to cause a connection reset, // as NetworkStream.Dispose() will call Shutdown(Both). _stream.Socket.Dispose(); } _stream.Dispose(); } catch (SocketException socketException) { return(ValueTask.FromException(ExceptionDispatchInfo.SetCurrentStackTrace(NetworkErrorHelper.MapSocketException(socketException)))); } catch (Exception ex) { return(ValueTask.FromException(ex)); } return(default);
public void OnCompleted() { if (_gatheredSegments != null) { _gatheredSegments.Clear(); if (_pooledArrays != null) { foreach (byte[] buffer in _pooledArrays) { ArrayPool <byte> .Shared.Return(buffer); } _pooledArrays.Clear(); } } if (SocketError == SocketError.Success) { SetResult(0); } else { SetException(ExceptionDispatchInfo.SetCurrentStackTrace(new IOException($"{nameof(WriteAsync)} failed. See InnerException for more details.", new SocketException((int)SocketError)))); } }
/// <summary>Gets a SocketException or an IOException wrapping a SocketException for the specified error.</summary> private static Exception GetException(SocketError error, bool wrapExceptionsInIOExceptions = false) { Exception e = ExceptionDispatchInfo.SetCurrentStackTrace(new SocketException((int)error)); return(wrapExceptionsInIOExceptions ? new IOException(SR.Format(SR.net_io_readwritefailure, e.Message), e) : e); }
private void CancelWaiter() { if (Interlocked.Exchange(ref _hasWaiter, 0) == 1) { Debug.Assert(_waitSourceCancellationToken != default); _waitSource.SetException(ExceptionDispatchInfo.SetCurrentStackTrace(new OperationCanceledException(_waitSourceCancellationToken))); } }
/// <inheritdoc/> public sealed override ValueTask <Connection> ConnectAsync(EndPoint?endPoint, IConnectionProperties?options = null, CancellationToken cancellationToken = default) { if (options == null || !options.TryGet(out DnsEndPointWithProperties? httpOptions)) { return(ValueTask.FromException <Connection>(ExceptionDispatchInfo.SetCurrentStackTrace(new HttpRequestException($"{nameof(SocketsHttpConnectionFactory)} requires a {nameof(DnsEndPointWithProperties)} property.")))); } return(EstablishConnectionAsync(httpOptions !.InitialRequest, endPoint, options, cancellationToken)); }
private void CancelWaiter() { if (Interlocked.Exchange(ref _hasWaiter, 0) == 1) { Debug.Assert(_waitSourceCancellationToken != default); #if NET5_0_OR_GREATER // API introduced in .NET 5 _waitSource.SetException(ExceptionDispatchInfo.SetCurrentStackTrace(new OperationCanceledException(_waitSourceCancellationToken))); #endif } }
private uint HandleEventShutdownInitiatedByTransport(ref ConnectionEvent connectionEvent) { if (!_connected) { uint hresult = connectionEvent.Data.ShutdownInitiatedByTransport.Status; Exception ex = QuicExceptionHelpers.CreateExceptionForHResult(hresult, "Connection has been shutdown by transport."); _connectTcs.SetException(ExceptionDispatchInfo.SetCurrentStackTrace(ex)); } return(MsQuicStatusCodes.Success); }
private uint HandleEventShutdownInitiatedByTransport(ref ConnectionEvent connectionEvent) { if (!_connected) { _connectTcs.SetException(ExceptionDispatchInfo.SetCurrentStackTrace(new IOException("Connection has been shutdown."))); } _acceptQueue.Writer.Complete(); return(MsQuicStatusCodes.Success); }
protected override async ValueTask CloseAsyncCore(ConnectionCloseMethod method, CancellationToken cancellationToken) { if (_originalPipe == null) { return; } Exception?inputException, outputException; if (method == ConnectionCloseMethod.GracefulShutdown) { // Flush happens implicitly from CompleteAsync(null), so only flush here if we need cancellation. if (cancellationToken.CanBeCanceled) { FlushResult r = await _originalPipe.Output.FlushAsync(cancellationToken).ConfigureAwait(false); if (r.IsCanceled) { cancellationToken.ThrowIfCancellationRequested(); } } inputException = null; outputException = null; } else { inputException = ExceptionDispatchInfo.SetCurrentStackTrace(new ObjectDisposedException(nameof(Connection))); outputException = ExceptionDispatchInfo.SetCurrentStackTrace(new ObjectDisposedException(nameof(Connection))); } await _originalPipe.Input.CompleteAsync(inputException).ConfigureAwait(false); await _originalPipe.Output.CompleteAsync(outputException).ConfigureAwait(false); if (!_leaveOpen) { switch (_originalPipe) { case IAsyncDisposable d: await d.DisposeAsync().ConfigureAwait(false); break; case IDisposable d: d.Dispose(); break; } } _originalPipe = null; }
private static uint HandleEventShutdownInitiatedByTransport(State state, ref ConnectionEvent connectionEvent) { if (!state.Connected) { Debug.Assert(state.Connection != null); state.Connection = null; uint hresult = connectionEvent.Data.ShutdownInitiatedByTransport.Status; Exception ex = QuicExceptionHelpers.CreateExceptionForHResult(hresult, "Connection has been shutdown by transport."); state.ConnectTcs.SetException(ExceptionDispatchInfo.SetCurrentStackTrace(ex)); } state.AcceptQueue.Writer.Complete(); return(MsQuicStatusCodes.Success); }
private static uint HandleEventShutdownComplete(State state, ref ConnectionEvent connectionEvent) { // This is the final event on the connection, so free the GCHandle used by the event callback. state.StateGCHandle.Free(); if (state.ListenerState != null) { // This is inbound connection that never got connected - becasue of TLS validation or some other reason. // Remove connection from pending queue and dispose it. if (state.ListenerState.PendingConnections.TryRemove(state.Handle.DangerousGetHandle(), out MsQuicConnection? connection)) { connection.Dispose(); } state.ListenerState = null; } state.Connection = null; state.ShutdownTcs.SetResult(MsQuicStatusCodes.Success); // Stop accepting new streams. state.AcceptQueue.Writer.TryComplete(); // Stop notifying about available streams. TaskCompletionSource?unidirectionalTcs = null; TaskCompletionSource?bidirectionalTcs = null; lock (state) { unidirectionalTcs = state.NewUnidirectionalStreamsAvailable; bidirectionalTcs = state.NewBidirectionalStreamsAvailable; state.NewUnidirectionalStreamsAvailable = null; state.NewBidirectionalStreamsAvailable = null; } if (unidirectionalTcs is not null) { unidirectionalTcs.SetException(ExceptionDispatchInfo.SetCurrentStackTrace(new QuicOperationAbortedException())); } if (bidirectionalTcs is not null) { bidirectionalTcs.SetException(ExceptionDispatchInfo.SetCurrentStackTrace(new QuicOperationAbortedException())); } return(MsQuicStatusCodes.Success); }
public override ValueTask WriteAsync(ReadOnlyMemory <byte> buffer, CancellationToken cancellationToken) { if (cancellationToken.IsCancellationRequested) { return(ValueTask.FromCanceled(cancellationToken)); } HttpConnection?connection = _connection; if (connection == null) { return(ValueTask.FromException(ExceptionDispatchInfo.SetCurrentStackTrace(new IOException(SR.ObjectDisposed_StreamClosed)))); } if (buffer.Length == 0) { return(default);
public static void SetCurrentStackTrace_Invalid_Throws() { Exception e; // Null argument e = null; AssertExtensions.Throws <ArgumentNullException>("source", () => ExceptionDispatchInfo.SetCurrentStackTrace(e)); // Previously set current stack e = new Exception(); ExceptionDispatchInfo.SetCurrentStackTrace(e); Assert.Throws <InvalidOperationException>(() => ExceptionDispatchInfo.SetCurrentStackTrace(e)); // Previously thrown e = new Exception(); try { throw e; } catch { } Assert.Throws <InvalidOperationException>(() => ExceptionDispatchInfo.SetCurrentStackTrace(e)); }
private static int HandleEventShutdownInitiatedByTransport(State state, ref QUIC_CONNECTION_EVENT connectionEvent) { if (!state.Connected && state.ConnectTcs != null) { Debug.Assert(state.Connection != null); state.Connection = null; Exception ex = new MsQuicException(connectionEvent.SHUTDOWN_INITIATED_BY_TRANSPORT.Status, "Connection has been shutdown by transport"); state.ConnectTcs !.SetException(ExceptionDispatchInfo.SetCurrentStackTrace(ex)); state.ConnectTcs = null; } // To throw QuicConnectionAbortedException (instead of QuicOperationAbortedException) out of AcceptStreamAsync() since // it wasn't our side who shutdown the connection. // We should rather keep the Status and propagate it either in a different exception or as a different field of QuicConnectionAbortedException. // See: https://github.com/dotnet/runtime/issues/60133 state.AbortErrorCode = 0; state.AcceptQueue.Writer.TryComplete(); return(QUIC_STATUS_SUCCESS); }
private void RegisterCancellation(CancellationToken cancellationToken) { _registration = cancellationToken.UnsafeRegister(s => { CancelableCreditWaiter thisRef = (CancelableCreditWaiter)s !; lock (thisRef._syncObj) { if (thisRef.IsPending) { thisRef._registration = default; // benign race with setting in the ctor thisRef._source.SetException(ExceptionDispatchInfo.SetCurrentStackTrace(new OperationCanceledException(thisRef._registration.Token))); // We don't remove it from the list as we lack a prev pointer that would enable us to do so correctly, // and it's not worth adding a prev pointer for the rare case of cancellation. We instead just // check when completing a waiter whether it's already been canceled. As such, we also do not // dispose it here. } } }, this); }
public void Dispose() { lock (SyncObject) { if (_disposed) { return; } _disposed = true; if (_waiters != null) { while (_waiters.TryDequeue(out Waiter waiter)) { waiter.TrySetException(ExceptionDispatchInfo.SetCurrentStackTrace(CreateObjectDisposedException(forActiveWaiter: true))); } } } }
private static uint HandleEventShutdownInitiatedByTransport(State state, ref ConnectionEvent connectionEvent) { if (!state.Connected && state.ConnectTcs != null) { Debug.Assert(state.Connection != null); state.Connection = null; uint hresult = connectionEvent.Data.ShutdownInitiatedByTransport.Status; Exception ex = QuicExceptionHelpers.CreateExceptionForHResult(hresult, "Connection has been shutdown by transport."); state.ConnectTcs !.SetException(ExceptionDispatchInfo.SetCurrentStackTrace(ex)); state.ConnectTcs = null; } // To throw QuicConnectionAbortedException (instead of QuicOperationAbortedException) out of AcceptStreamAsync() since // it wasn't our side who shutdown the connection. // We should rather keep the Status and propagate it either in a different exception or as a different field of QuicConnectionAbortedException. // See: https://github.com/dotnet/runtime/issues/60133 state.AbortErrorCode = 0; state.AcceptQueue.Writer.TryComplete(); return(MsQuicStatusCodes.Success); }
static void Method3() { try { throw new Exception("Exception3"); } catch (Exception ex) { logger.Error(ex); ExceptionDispatchInfo.SetCurrentStackTrace(ex); StackTrace stackTrace = new StackTrace(ex); StackFrame[] frames = stackTrace.GetFrames(); for (int i = 0; i < frames.Length; i++) { StackFrame sf = frames[i]; } stackTrace = new StackTrace(true); frames = stackTrace.GetFrames(); for (int i = 0; i < frames.Length; i++) { StackFrame sf = frames[i]; } if (Debugger.IsAttached) { Debug.WriteLine(ex); } Console.WriteLine(ex); Console.WriteLine(ex.ToString()); } throw new Exception("Exception"); }
protected override void OnCompleted(SocketAsyncEventArgs _) { switch (SocketError) { case SocketError.Success: Builder.SetResult(); break; case SocketError.OperationAborted: case SocketError.ConnectionAborted: if (CancellationToken.IsCancellationRequested) { Builder.SetException(ExceptionDispatchInfo.SetCurrentStackTrace(CancellationHelper.CreateOperationCanceledException(null, CancellationToken))); break; } goto default; default: Builder.SetException(ExceptionDispatchInfo.SetCurrentStackTrace(new SocketException((int)SocketError))); break; } }
public static Task <byte[]> ReadAllBytesAsync(string path, CancellationToken cancellationToken = default(CancellationToken)) { if (cancellationToken.IsCancellationRequested) { return(Task.FromCanceled <byte[]>(cancellationToken)); } var fs = new FileStream( path, FileMode.Open, FileAccess.Read, FileShare.Read, bufferSize: 1, // bufferSize == 1 used to avoid unnecessary buffer in FileStream FileOptions.Asynchronous | FileOptions.SequentialScan); bool returningInternalTask = false; try { long fileLength = fs.Length; if (fileLength > int.MaxValue) { var e = new IOException(SR.IO_FileTooLong2GB); #if !MS_IO_REDIST ExceptionDispatchInfo.SetCurrentStackTrace(e); #endif return(Task.FromException <byte[]>(e)); } returningInternalTask = true; return(fileLength > 0 ? InternalReadAllBytesAsync(fs, (int)fileLength, cancellationToken) : InternalReadAllBytesUnknownLengthAsync(fs, cancellationToken)); } finally { if (!returningInternalTask) { fs.Dispose(); } } }
protected override void HandleUnexpectedCancellation() => TrySetException(ExceptionDispatchInfo.SetCurrentStackTrace(Error.GetOperationAborted()));
/// <inheritdoc/> public override ValueTask <ConnectionListener> ListenAsync(EndPoint?endPoint, IConnectionProperties?options = null, CancellationToken cancellationToken = default) { return(ValueTask.FromException <ConnectionListener>(ExceptionDispatchInfo.SetCurrentStackTrace(new NotSupportedException($"{nameof(HttpTunnelConnectionFactory)} does not support listening.")))); }
private ValueTask WriteSingleChunk <TIOAdapter>(TIOAdapter writeAdapter, ReadOnlyMemory <byte> buffer) where TIOAdapter : struct, ISslIOAdapter { // Request a write IO slot. Task ioSlot = writeAdapter.WriteLockAsync(); if (!ioSlot.IsCompletedSuccessfully) { // Operation is async and has been queued, return. return(WaitForWriteIOSlot(writeAdapter, ioSlot, buffer)); } byte[] rentedBuffer = ArrayPool <byte> .Shared.Rent(buffer.Length + FrameOverhead); byte[] outBuffer = rentedBuffer; SecurityStatusPal status = EncryptData(buffer, ref outBuffer, out int encryptedBytes); if (status.ErrorCode != SecurityStatusPalErrorCode.OK) { // Re-handshake status is not supported. ArrayPool <byte> .Shared.Return(rentedBuffer); ProtocolToken message = new ProtocolToken(null, status); return(new ValueTask(Task.FromException(ExceptionDispatchInfo.SetCurrentStackTrace(new IOException(SR.net_io_encrypt, message.GetException()))))); } ValueTask t = writeAdapter.WriteAsync(outBuffer, 0, encryptedBytes); if (t.IsCompletedSuccessfully) { ArrayPool <byte> .Shared.Return(rentedBuffer); FinishWrite(); return(t); } else { return(CompleteAsync(t, rentedBuffer)); } async ValueTask WaitForWriteIOSlot(TIOAdapter wAdapter, Task lockTask, ReadOnlyMemory <byte> buff) { await lockTask.ConfigureAwait(false); await WriteSingleChunk(wAdapter, buff).ConfigureAwait(false); } async ValueTask CompleteAsync(ValueTask writeTask, byte[] bufferToReturn) { try { await writeTask.ConfigureAwait(false); } finally { ArrayPool <byte> .Shared.Return(bufferToReturn); FinishWrite(); } } }
protected internal sealed override Task <HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { if (request == null) { throw new ArgumentNullException(nameof(request), SR.net_http_handler_norequest); } // ProcessRequest() and ProcessResponse() are supposed to be fast, so we call ProcessRequest() on the same // thread SendAsync() was invoked to avoid context switches. However, if ProcessRequest() throws, we have // to catch the exception since the caller doesn't expect exceptions when calling SendAsync(): The // expectation is that the returned task will get faulted on errors, but the async call to SendAsync() // should complete. var tcs = new SendState(this, cancellationToken); try { HttpRequestMessage newRequestMessage = ProcessRequest(request, cancellationToken); Task <HttpResponseMessage> sendAsyncTask = base.SendAsync(newRequestMessage, cancellationToken); // We schedule a continuation task once the inner handler completes in order to trigger the response // processing method. ProcessResponse() is only called if the task wasn't canceled before. sendAsyncTask.ContinueWithStandard(tcs, (task, state) => { var sendState = (SendState)state; MessageProcessingHandler self = sendState._handler; CancellationToken token = sendState._token; if (task.IsFaulted) { sendState.TrySetException(task.Exception.GetBaseException()); return; } if (task.IsCanceled) { sendState.TrySetCanceled(); return; } if (task.Result == null) { sendState.TrySetException(ExceptionDispatchInfo.SetCurrentStackTrace(new InvalidOperationException(SR.net_http_handler_noresponse))); return; } try { HttpResponseMessage responseMessage = self.ProcessResponse(task.Result, token); sendState.TrySetResult(responseMessage); } catch (OperationCanceledException e) { // If ProcessResponse() throws an OperationCanceledException check whether it is related to // the cancellation token we received from the user. If so, cancel the Task. HandleCanceledOperations(token, sendState, e); } catch (Exception e) { sendState.TrySetException(e); } // We don't pass the cancellation token to the continuation task, since we want to get called even // if the operation was canceled: We'll set the Task returned to the user to canceled. Passing the // cancellation token here would result in the continuation task to not be called at all. I.e. we // would never complete the task returned to the caller of SendAsync(). }); } catch (OperationCanceledException e) { HandleCanceledOperations(cancellationToken, tcs, e); } catch (Exception e) { tcs.TrySetException(e); } return(tcs.Task); }
private static void ABCDEFGHIJKLMNOPQRSTUVWXYZ(Exception e) { Assert.Same(e, ExceptionDispatchInfo.SetCurrentStackTrace(e)); }