public void FlushAsyncCancellationDeadlock() { var cts = new CancellationTokenSource(); var cts2 = new CancellationTokenSource(); var e = new ManualResetEventSlim(); PipeAwaiter <ReadResult> awaiter = Pipe.Reader.ReadAsync(cts.Token); awaiter.OnCompleted( () => { // We are on cancellation thread and need to wait untill another ReadAsync call // takes pipe state lock e.Wait(); // Make sure we had enough time to reach _cancellationTokenRegistration.Dispose Thread.Sleep(100); // Try to take pipe state lock Pipe.Reader.ReadAsync(); }); // Start a thread that would run cancellation calbacks Task cancellationTask = Task.Run(() => cts.Cancel()); // Start a thread that would call ReadAsync with different token // and block on _cancellationTokenRegistration.Dispose Task blockingTask = Task.Run( () => { e.Set(); Pipe.Reader.ReadAsync(cts2.Token); }); bool completed = Task.WhenAll(cancellationTask, blockingTask).Wait(TimeSpan.FromSeconds(10)); Assert.True(completed); }
public void ReadAsyncReturnsIsCancelOnCancelPendingReadBeforeGetResult() { PipeAwaiter <ReadResult> awaitable = Pipe.Reader.ReadAsync(); Assert.False(awaitable.IsCompleted); awaitable.OnCompleted(() => { }); Pipe.Writer.WriteAsync(new byte[] { }); Pipe.Reader.CancelPendingRead(); Assert.True(awaitable.IsCompleted); ReadResult result = awaitable.GetResult(); Assert.True(result.IsCanceled); }
public void FlushAsyncReturnsIsCancelOnCancelPendingFlushBeforeGetResult() { PipeWriter writableBuffer = Pipe.Writer.WriteEmpty(MaximumSizeHigh); PipeAwaiter <FlushResult> awaitable = writableBuffer.FlushAsync(); Assert.False(awaitable.IsCompleted); awaitable.OnCompleted(() => { }); Pipe.Reader.AdvanceTo(Pipe.Reader.ReadAsync().GetResult().Buffer.End); Pipe.Writer.CancelPendingFlush(); Assert.True(awaitable.IsCompleted); FlushResult result = awaitable.GetResult(); Assert.True(result.IsCanceled); }
public void GetResultThrowsIfReadAsyncCanceledBeforeOnCompleted() { var onCompletedCalled = false; var cancellationTokenSource = new CancellationTokenSource(); PipeAwaiter <ReadResult> awaiter = Pipe.Reader.ReadAsync(cancellationTokenSource.Token); bool awaiterIsCompleted = awaiter.IsCompleted; cancellationTokenSource.Cancel(); awaiter.OnCompleted( () => { onCompletedCalled = true; Assert.Throws <OperationCanceledException>(() => awaiter.GetResult()); }); Assert.False(awaiterIsCompleted); Assert.True(onCompletedCalled); }
private async Task FlushAsyncAwaited(PipeAwaiter <FlushResult> awaitable, CancellationToken cancellationToken) { // https://github.com/dotnet/corefxlab/issues/1334 // Since the flush awaitable doesn't currently support multiple awaiters // we need to use a task to track the callbacks. // All awaiters get the same task lock (_flushLock) { if (_flushTcs == null || _flushTcs.Task.IsCompleted) { _flushTcs = new TaskCompletionSource <object>(); awaitable.OnCompleted(_flushCompleted); } } await _flushTcs.Task; cancellationToken.ThrowIfCancellationRequested(); }
public void GetResultThrowsIfFlushAsyncCancelledBeforeOnCompleted() { var onCompletedCalled = false; var cancellationTokenSource = new CancellationTokenSource(); PipeWriter buffer = Pipe.Writer.WriteEmpty(MaximumSizeHigh); PipeAwaiter <FlushResult> awaiter = buffer.FlushAsync(cancellationTokenSource.Token); bool awaiterIsCompleted = awaiter.IsCompleted; cancellationTokenSource.Cancel(); awaiter.OnCompleted( () => { onCompletedCalled = true; Assert.Throws <OperationCanceledException>(() => awaiter.GetResult()); }); Assert.False(awaiterIsCompleted); Assert.True(onCompletedCalled); }
public void OnWriterCompletedRanBeforeReadContinuation() { var callbackRan = false; var continuationRan = false; var pipe = new Pipe(new PipeOptions(_pool)); pipe.Reader.OnWriterCompleted( (exception, state) => { callbackRan = true; Assert.False(continuationRan); }, null); PipeAwaiter <ReadResult> awaiter = pipe.Reader.ReadAsync(); Assert.False(awaiter.IsCompleted); awaiter.OnCompleted(() => { continuationRan = true; }); pipe.Writer.Complete(); Assert.True(callbackRan); }
public void ReadAsyncNotCompletedAfterCancellationTokenCanceled() { var onCompletedCalled = false; var cts = new CancellationTokenSource(); PipeAwaiter <ReadResult> awaitable = Pipe.Reader.ReadAsync(cts.Token); Assert.False(awaitable.IsCompleted); awaitable.OnCompleted( () => { onCompletedCalled = true; Assert.True(awaitable.IsCompleted); Assert.Throws <OperationCanceledException>(() => awaitable.GetResult()); awaitable = Pipe.Reader.ReadAsync(); Assert.False(awaitable.IsCompleted); }); cts.Cancel(); Assert.True(onCompletedCalled); }
public void ReadAsyncNotCompletedAfterCancellation() { var onCompletedCalled = false; PipeAwaiter <ReadResult> awaitable = Pipe.Reader.ReadAsync(); Assert.False(awaitable.IsCompleted); awaitable.OnCompleted( () => { onCompletedCalled = true; Assert.True(awaitable.IsCompleted); ReadResult readResult = awaitable.GetResult(); Assert.True(readResult.IsCanceled); awaitable = Pipe.Reader.ReadAsync(); Assert.False(awaitable.IsCompleted); }); Pipe.Reader.CancelPendingRead(); Assert.True(onCompletedCalled); }
public void OnReaderCompletedRanBeforeFlushContinuation() { var callbackRan = false; var continuationRan = false; var pipe = new Pipe(new PipeOptions(_pool, pauseWriterThreshold: 5)); pipe.Writer.OnReaderCompleted( (exception, state) => { Assert.False(continuationRan); callbackRan = true; }, null); PipeWriter buffer = pipe.Writer.WriteEmpty(10); PipeAwaiter <FlushResult> awaiter = buffer.FlushAsync(); Assert.False(awaiter.IsCompleted); awaiter.OnCompleted(() => { continuationRan = true; }); pipe.Reader.Complete(); Assert.True(callbackRan); pipe.Writer.Complete(); }
public void FlushAsyncNotCompletedAfterCancellationTokenCancelled() { var onCompletedCalled = false; var cts = new CancellationTokenSource(); PipeWriter writableBuffer = Pipe.Writer.WriteEmpty(MaximumSizeHigh); PipeAwaiter <FlushResult> awaitable = writableBuffer.FlushAsync(cts.Token); Assert.False(awaitable.IsCompleted); awaitable.OnCompleted( () => { onCompletedCalled = true; Assert.True(awaitable.IsCompleted); Assert.Throws <OperationCanceledException>(() => awaitable.GetResult()); awaitable = writableBuffer.FlushAsync(); Assert.False(awaitable.IsCompleted); }); cts.Cancel(); Assert.True(onCompletedCalled); }
public void FlushAsyncNotCompletedAfterCancellation() { var onCompletedCalled = false; PipeWriter writableBuffer = Pipe.Writer.WriteEmpty(MaximumSizeHigh); PipeAwaiter <FlushResult> awaitable = writableBuffer.FlushAsync(); Assert.False(awaitable.IsCompleted); awaitable.OnCompleted( () => { onCompletedCalled = true; Assert.True(awaitable.IsCompleted); FlushResult flushResult = awaitable.GetResult(); Assert.True(flushResult.IsCanceled); awaitable = writableBuffer.FlushAsync(); Assert.False(awaitable.IsCompleted); }); Pipe.Writer.CancelPendingFlush(); Assert.True(onCompletedCalled); }