Browse Source

Merge pull request #1756 from SixLabors/af/fix-1755

Fix ManagedBufferBase pinning behavior
pull/1771/head
James Jackson-South 5 years ago
committed by GitHub
parent
commit
2b85b553f3
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 6
      src/ImageSharp/Memory/Allocators/Internals/ManagedBufferBase.cs
  2. 17
      tests/ImageSharp.Tests/Memory/Allocators/ArrayPoolMemoryAllocatorTests.cs
  3. 20
      tests/ImageSharp.Tests/Memory/Allocators/SimpleGcMemoryAllocatorTests.cs

6
src/ImageSharp/Memory/Allocators/Internals/ManagedBufferBase.cs

@ -24,7 +24,9 @@ namespace SixLabors.ImageSharp.Memory.Internals
} }
void* ptr = (void*)this.pinHandle.AddrOfPinnedObject(); void* ptr = (void*)this.pinHandle.AddrOfPinnedObject();
return new MemoryHandle(ptr, this.pinHandle);
// We should only pass pinnable:this, when GCHandle lifetime is managed by the MemoryManager<T> instance.
return new MemoryHandle(ptr, pinnable: this);
} }
/// <inheritdoc /> /// <inheritdoc />
@ -42,4 +44,4 @@ namespace SixLabors.ImageSharp.Memory.Internals
/// <returns>The pinnable <see cref="object"/>.</returns> /// <returns>The pinnable <see cref="object"/>.</returns>
protected abstract object GetPinnableObject(); protected abstract object GetPinnableObject();
} }
} }

17
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<byte> memoryOwner = allocator.Allocate<byte>(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] [Theory]
[InlineData(false)] [InlineData(false)]
[InlineData(true)] [InlineData(true)]

20
tests/ImageSharp.Tests/Memory/Allocators/SimpleGcMemoryAllocatorTests.cs

@ -2,6 +2,7 @@
// Licensed under the Apache License, Version 2.0. // Licensed under the Apache License, Version 2.0.
using System; using System;
using System.Buffers;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using SixLabors.ImageSharp.Memory; using SixLabors.ImageSharp.Memory;
using Xunit; using Xunit;
@ -36,9 +37,26 @@ namespace SixLabors.ImageSharp.Tests.Memory.Allocators
Assert.Equal("length", ex.ParamName); Assert.Equal("length", ex.ParamName);
} }
[Fact]
public unsafe void Allocate_MemoryIsPinnableMultipleTimes()
{
SimpleGcMemoryAllocator allocator = this.MemoryAllocator;
using IMemoryOwner<byte> memoryOwner = allocator.Allocate<byte>(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)] [StructLayout(LayoutKind.Explicit, Size = 512)]
private struct BigStruct private struct BigStruct
{ {
} }
} }
} }

Loading…
Cancel
Save