From f4a3a0e76b1f1b3dc279b771f8ea7bf632943528 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Fri, 27 Aug 2021 16:56:57 +0200 Subject: [PATCH] fix ManagedBufferBase pinning behavior --- .../Allocators/Internals/ManagedBufferBase.cs | 4 ++-- .../ArrayPoolMemoryAllocatorTests.cs | 17 ++++++++++++++++ .../SimpleGcMemoryAllocatorTests.cs | 20 ++++++++++++++++++- 3 files changed, 38 insertions(+), 3 deletions(-) diff --git a/src/ImageSharp/Memory/Allocators/Internals/ManagedBufferBase.cs b/src/ImageSharp/Memory/Allocators/Internals/ManagedBufferBase.cs index 3f54e335e..f88c3a5f4 100644 --- a/src/ImageSharp/Memory/Allocators/Internals/ManagedBufferBase.cs +++ b/src/ImageSharp/Memory/Allocators/Internals/ManagedBufferBase.cs @@ -24,7 +24,7 @@ namespace SixLabors.ImageSharp.Memory.Internals } void* ptr = (void*)this.pinHandle.AddrOfPinnedObject(); - return new MemoryHandle(ptr, this.pinHandle); + return new MemoryHandle(ptr, this.pinHandle, this); } /// @@ -42,4 +42,4 @@ namespace SixLabors.ImageSharp.Memory.Internals /// The pinnable . protected abstract object GetPinnableObject(); } -} \ No newline at end of file +} diff --git a/tests/ImageSharp.Tests/Memory/Allocators/ArrayPoolMemoryAllocatorTests.cs b/tests/ImageSharp.Tests/Memory/Allocators/ArrayPoolMemoryAllocatorTests.cs index 7620d63de..dd53b0b56 100644 --- a/tests/ImageSharp.Tests/Memory/Allocators/ArrayPoolMemoryAllocatorTests.cs +++ b/tests/ImageSharp.Tests/Memory/Allocators/ArrayPoolMemoryAllocatorTests.cs @@ -114,6 +114,23 @@ namespace SixLabors.ImageSharp.Tests.Memory.Allocators } } + [Fact] + public unsafe void Allocate_MemoryIsPinnableMultipleTimes() + { + ArrayPoolMemoryAllocator allocator = this.LocalFixture.MemoryAllocator; + using IMemoryOwner memoryOwner = allocator.Allocate(100); + + using (MemoryHandle pin = memoryOwner.Memory.Pin()) + { + Assert.NotEqual(IntPtr.Zero, (IntPtr)pin.Pointer); + } + + using (MemoryHandle pin = memoryOwner.Memory.Pin()) + { + Assert.NotEqual(IntPtr.Zero, (IntPtr)pin.Pointer); + } + } + [Theory] [InlineData(false)] [InlineData(true)] diff --git a/tests/ImageSharp.Tests/Memory/Allocators/SimpleGcMemoryAllocatorTests.cs b/tests/ImageSharp.Tests/Memory/Allocators/SimpleGcMemoryAllocatorTests.cs index 8e7b30567..0e1f99725 100644 --- a/tests/ImageSharp.Tests/Memory/Allocators/SimpleGcMemoryAllocatorTests.cs +++ b/tests/ImageSharp.Tests/Memory/Allocators/SimpleGcMemoryAllocatorTests.cs @@ -2,6 +2,7 @@ // Licensed under the Apache License, Version 2.0. using System; +using System.Buffers; using System.Runtime.InteropServices; using SixLabors.ImageSharp.Memory; using Xunit; @@ -36,9 +37,26 @@ namespace SixLabors.ImageSharp.Tests.Memory.Allocators Assert.Equal("length", ex.ParamName); } + [Fact] + public unsafe void Allocate_MemoryIsPinnableMultipleTimes() + { + SimpleGcMemoryAllocator allocator = this.MemoryAllocator; + using IMemoryOwner memoryOwner = allocator.Allocate(100); + + using (MemoryHandle pin = memoryOwner.Memory.Pin()) + { + Assert.NotEqual(IntPtr.Zero, (IntPtr)pin.Pointer); + } + + using (MemoryHandle pin = memoryOwner.Memory.Pin()) + { + Assert.NotEqual(IntPtr.Zero, (IntPtr)pin.Pointer); + } + } + [StructLayout(LayoutKind.Explicit, Size = 512)] private struct BigStruct { } } -} \ No newline at end of file +}