From a58e6ff53d6f61f283446368cc8ee0dbc4020e4c Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Thu, 8 Dec 2022 11:16:09 +1000 Subject: [PATCH 1/4] Add more cancellation checks --- src/ImageSharp/IO/BufferedReadStream.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/ImageSharp/IO/BufferedReadStream.cs b/src/ImageSharp/IO/BufferedReadStream.cs index 9200dbf7f..efa8f6f4b 100644 --- a/src/ImageSharp/IO/BufferedReadStream.cs +++ b/src/ImageSharp/IO/BufferedReadStream.cs @@ -90,6 +90,7 @@ internal sealed class BufferedReadStream : Stream set { Guard.MustBeGreaterThanOrEqualTo(value, 0, nameof(this.Position)); + this.cancellationToken.ThrowIfCancellationRequested(); // Only reset readBufferIndex if we are out of bounds of our working buffer // otherwise we should simply move the value by the diff. @@ -262,6 +263,7 @@ internal sealed class BufferedReadStream : Stream [MethodImpl(MethodImplOptions.NoInlining)] private void FillReadBuffer() { + this.cancellationToken.ThrowIfCancellationRequested(); Stream baseStream = this.BaseStream; if (this.readerPosition != baseStream.Position) { From e2c574856ed087e58f776d9f6a5f10ef87b72cf5 Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Thu, 8 Dec 2022 15:26:40 +1000 Subject: [PATCH 2/4] Base the buffer size on the stream length --- .../ImageSharp.Tests/Image/ImageTests.Decode_Cancellation.cs | 2 +- tests/ImageSharp.Tests/TestUtilities/IPausedStream.cs | 2 ++ tests/ImageSharp.Tests/TestUtilities/PausedMemoryStream.cs | 4 ++-- tests/ImageSharp.Tests/TestUtilities/PausedStream.cs | 4 ++-- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/tests/ImageSharp.Tests/Image/ImageTests.Decode_Cancellation.cs b/tests/ImageSharp.Tests/Image/ImageTests.Decode_Cancellation.cs index 6b74e9b35..543dd28cd 100644 --- a/tests/ImageSharp.Tests/Image/ImageTests.Decode_Cancellation.cs +++ b/tests/ImageSharp.Tests/Image/ImageTests.Decode_Cancellation.cs @@ -85,7 +85,7 @@ public partial class ImageTests Configuration configuration = Configuration.CreateDefaultInstance(); configuration.FileSystem = new SingleStreamFileSystem((Stream)pausedStream); - configuration.StreamProcessingBufferSize = 256; + configuration.StreamProcessingBufferSize = (int)Math.Min(128, pausedStream.Length / 4); DecoderOptions options = new() { diff --git a/tests/ImageSharp.Tests/TestUtilities/IPausedStream.cs b/tests/ImageSharp.Tests/TestUtilities/IPausedStream.cs index 1eedef9d0..ec9b2e7e1 100644 --- a/tests/ImageSharp.Tests/TestUtilities/IPausedStream.cs +++ b/tests/ImageSharp.Tests/TestUtilities/IPausedStream.cs @@ -12,4 +12,6 @@ public interface IPausedStream : IDisposable public void Next(); public void Release(); + + public long Length { get; } } diff --git a/tests/ImageSharp.Tests/TestUtilities/PausedMemoryStream.cs b/tests/ImageSharp.Tests/TestUtilities/PausedMemoryStream.cs index 5b285b4ca..ae4af24f1 100644 --- a/tests/ImageSharp.Tests/TestUtilities/PausedMemoryStream.cs +++ b/tests/ImageSharp.Tests/TestUtilities/PausedMemoryStream.cs @@ -12,9 +12,9 @@ namespace SixLabors.ImageSharp.Tests.TestUtilities; /// public class PausedMemoryStream : MemoryStream, IPausedStream { - private readonly SemaphoreSlim semaphore = new SemaphoreSlim(0); + private readonly SemaphoreSlim semaphore = new(0); - private readonly CancellationTokenSource cancelationTokenSource = new CancellationTokenSource(); + private readonly CancellationTokenSource cancelationTokenSource = new(); private Action onWaitingCallback; diff --git a/tests/ImageSharp.Tests/TestUtilities/PausedStream.cs b/tests/ImageSharp.Tests/TestUtilities/PausedStream.cs index 8af168d67..3c780f347 100644 --- a/tests/ImageSharp.Tests/TestUtilities/PausedStream.cs +++ b/tests/ImageSharp.Tests/TestUtilities/PausedStream.cs @@ -7,9 +7,9 @@ namespace SixLabors.ImageSharp.Tests.TestUtilities; public class PausedStream : Stream, IPausedStream { - private readonly SemaphoreSlim semaphore = new SemaphoreSlim(0); + private readonly SemaphoreSlim semaphore = new(0); - private readonly CancellationTokenSource cancelationTokenSource = new CancellationTokenSource(); + private readonly CancellationTokenSource cancelationTokenSource = new(); private readonly Stream innerStream; private Action onWaitingCallback; From 718bdc49d0781a3ded0d1096182fcda977e98437 Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Thu, 8 Dec 2022 20:43:31 +1000 Subject: [PATCH 3/4] Experiment with a much shorter timeout. --- tests/ImageSharp.Tests/Image/ImageTests.Decode_Cancellation.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/ImageSharp.Tests/Image/ImageTests.Decode_Cancellation.cs b/tests/ImageSharp.Tests/Image/ImageTests.Decode_Cancellation.cs index 543dd28cd..e6dac1472 100644 --- a/tests/ImageSharp.Tests/Image/ImageTests.Decode_Cancellation.cs +++ b/tests/ImageSharp.Tests/Image/ImageTests.Decode_Cancellation.cs @@ -95,7 +95,7 @@ public partial class ImageTests await Assert.ThrowsAnyAsync(async () => { using Image image = await Image.LoadAsync(options, "someFakeFile", cts.Token); - }).WaitAsync(TimeSpan.FromSeconds(30)); + }).WaitAsync(TimeSpan.FromMilliseconds(600)); } } } From 5f488eef7363600654f5a5bfaa53103b887eca05 Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Thu, 8 Dec 2022 20:55:51 +1000 Subject: [PATCH 4/4] Revert "Experiment with a much shorter timeout." This reverts commit 718bdc49d0781a3ded0d1096182fcda977e98437. --- tests/ImageSharp.Tests/Image/ImageTests.Decode_Cancellation.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/ImageSharp.Tests/Image/ImageTests.Decode_Cancellation.cs b/tests/ImageSharp.Tests/Image/ImageTests.Decode_Cancellation.cs index e6dac1472..543dd28cd 100644 --- a/tests/ImageSharp.Tests/Image/ImageTests.Decode_Cancellation.cs +++ b/tests/ImageSharp.Tests/Image/ImageTests.Decode_Cancellation.cs @@ -95,7 +95,7 @@ public partial class ImageTests await Assert.ThrowsAnyAsync(async () => { using Image image = await Image.LoadAsync(options, "someFakeFile", cts.Token); - }).WaitAsync(TimeSpan.FromMilliseconds(600)); + }).WaitAsync(TimeSpan.FromSeconds(30)); } } }