Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Commit a33de3c

Browse files
authored
Change OwnedMemory to MemoryManager and add an IMemoryOwner. (#17340)
* Change OwnedMemory to MemoryManager and add an IMemoryOwner. * Fix comments. * Reset start and length if TryGetMemoryManager returns false. * Reset start and length if TryGetMemoryManager returns false [actually]. * Re-order MemoryHandle ctor parameters and rename TOwner to TManager. * Fix formatting, remove unused code, and fix impl of Pin()
1 parent 59ff25b commit a33de3c

File tree

12 files changed

+266
-310
lines changed

12 files changed

+266
-310
lines changed

src/mscorlib/shared/System.Private.CoreLib.Shared.projitems

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,10 @@
4646
<Compile Include="$(MSBuildThisFileDirectory)System\Buffers\ArrayPool.cs" />
4747
<Compile Include="$(MSBuildThisFileDirectory)System\Buffers\ArrayPoolEventSource.cs" />
4848
<Compile Include="$(MSBuildThisFileDirectory)System\Buffers\ConfigurableArrayPool.cs" />
49-
<Compile Include="$(MSBuildThisFileDirectory)System\Buffers\IRetainable.cs" />
49+
<Compile Include="$(MSBuildThisFileDirectory)System\Buffers\IMemoryOwner.cs" />
50+
<Compile Include="$(MSBuildThisFileDirectory)System\Buffers\IPinnable.cs" />
5051
<Compile Include="$(MSBuildThisFileDirectory)System\Buffers\MemoryHandle.cs" />
51-
<Compile Include="$(MSBuildThisFileDirectory)System\Buffers\OwnedMemory.cs" />
52+
<Compile Include="$(MSBuildThisFileDirectory)System\Buffers\MemoryManager.cs" />
5253
<Compile Include="$(MSBuildThisFileDirectory)System\Buffers\TlsOverPerCoreLockedStacksArrayPool.cs" />
5354
<Compile Include="$(MSBuildThisFileDirectory)System\Buffers\Utilities.cs" />
5455
<Compile Include="$(MSBuildThisFileDirectory)System\Byte.cs" />
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
// See the LICENSE file in the project root for more information.
4+
5+
namespace System.Buffers
6+
{
7+
/// <summary>
8+
/// Owner of Memory<typeparamref name="T"/> that is responsible for disposing the underlying memory appropriately.
9+
/// </summary>
10+
public interface IMemoryOwner<T> : IDisposable
11+
{
12+
/// <summary>
13+
/// Returns a Memory<typeparamref name="T"/>.
14+
/// </summary>
15+
Memory<T> Memory { get; }
16+
}
17+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
// See the LICENSE file in the project root for more information.
4+
5+
namespace System.Buffers
6+
{
7+
/// <summary>
8+
/// Provides a mechanism for pinning and unpinning objects to prevent the GC from moving them.
9+
/// </summary>
10+
public interface IPinnable
11+
{
12+
/// <summary>
13+
/// Call this method to indicate that the IPinnable object can not be moved by the garbage collector.
14+
/// The address of the pinned object can be taken.
15+
/// <param name="elementIndex">The offset to the element within the memory at which the returned <see cref="MemoryHandle"/> points to.</param>
16+
/// </summary>
17+
MemoryHandle Pin(int elementIndex);
18+
19+
/// <summary>
20+
/// Call this method to indicate that the IPinnable object no longer needs to be pinned.
21+
/// The garbage collector is free to move the object now.
22+
/// </summary>
23+
void Unpin();
24+
}
25+
}

src/mscorlib/shared/System/Buffers/IRetainable.cs

Lines changed: 0 additions & 26 deletions
This file was deleted.

src/mscorlib/shared/System/Buffers/MemoryHandle.cs

Lines changed: 12 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -12,53 +12,48 @@ namespace System.Buffers
1212
/// </summary>
1313
public unsafe struct MemoryHandle : IDisposable
1414
{
15-
private IRetainable _retainable;
1615
private void* _pointer;
1716
private GCHandle _handle;
17+
private IPinnable _pinnable;
1818

1919
/// <summary>
2020
/// Creates a new memory handle for the memory.
2121
/// </summary>
22-
/// <param name="retainable">reference to manually managed object</param>
23-
/// <param name="pointer">pointer to memory, or null if a pointer was not provided when the handle was created</param>
22+
/// <param name="pointer">pointer to memory</param>
23+
/// <param name="pinnable">reference to manually managed object, or default if there is no memory manager</param>
2424
/// <param name="handle">handle used to pin array buffers</param>
2525
[CLSCompliant(false)]
26-
public MemoryHandle(IRetainable retainable, void* pointer = null, GCHandle handle = default(GCHandle))
26+
public MemoryHandle(void* pointer, GCHandle handle = default, IPinnable pinnable = default)
2727
{
28-
_retainable = retainable;
2928
_pointer = pointer;
3029
_handle = handle;
30+
_pinnable = pinnable;
3131
}
3232

3333
/// <summary>
34-
/// Returns the pointer to memory, or null if a pointer was not provided when the handle was created.
34+
/// Returns the pointer to memory, where the memory is assumed to be pinned and hence the address won't change.
3535
/// </summary>
3636
[CLSCompliant(false)]
3737
public void* Pointer => _pointer;
3838

3939
/// <summary>
40-
/// Returns false if the pointer to memory is null.
40+
/// Frees the pinned handle and releases IPinnable.
4141
/// </summary>
42-
public bool HasPointer => _pointer != null;
43-
44-
/// <summary>
45-
/// Frees the pinned handle and releases IRetainable.
46-
/// </summary>
47-
public void Dispose()
42+
public void Dispose()
4843
{
4944
if (_handle.IsAllocated)
5045
{
5146
_handle.Free();
5247
}
5348

54-
if (_retainable != null)
49+
if (_pinnable != null)
5550
{
56-
_retainable.Release();
57-
_retainable = null;
51+
_pinnable.Unpin();
52+
_pinnable = null;
5853
}
5954

6055
_pointer = null;
6156
}
6257

6358
}
64-
}
59+
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
// See the LICENSE file in the project root for more information.
4+
5+
using System.Runtime;
6+
using System.Runtime.CompilerServices;
7+
8+
namespace System.Buffers
9+
{
10+
/// <summary>
11+
/// Manager of Memory<typeparamref name="T"/> that provides the implementation.
12+
/// </summary>
13+
public abstract class MemoryManager<T> : IMemoryOwner<T>, IPinnable
14+
{
15+
/// <summary>
16+
/// The number of items in the Memory<typeparamref name="T"/>.
17+
/// </summary>
18+
public virtual int Length => GetSpan().Length;
19+
20+
/// <summary>
21+
/// Returns a Memory<typeparamref name="T"/>.
22+
/// </summary>
23+
public virtual Memory<T> Memory => new Memory<T>(this, 0, Length);
24+
25+
/// <summary>
26+
/// Returns a span wrapping the underlying memory.
27+
/// </summary>
28+
public abstract Span<T> GetSpan();
29+
30+
/// <summary>
31+
/// Returns a handle to the memory that has been pinned and hence its address can be taken.
32+
/// <param name="elementIndex">The offset to the element within the memory at which the returned <see cref="MemoryHandle"/> points to. (default = 0)</param>
33+
/// </summary>
34+
public abstract MemoryHandle Pin(int elementIndex = 0);
35+
36+
/// <summary>
37+
/// Lets the garbage collector know that the object is free to be moved now.
38+
/// </summary>
39+
public abstract void Unpin();
40+
41+
/// <summary>
42+
/// Returns an array segment.
43+
/// <remarks>Returns the default array segment if not overriden.</remarks>
44+
/// </summary>
45+
protected internal virtual bool TryGetArray(out ArraySegment<T> segment)
46+
{
47+
segment = default;
48+
return false;
49+
}
50+
51+
/// <summary>
52+
/// Implements IDisposable.
53+
/// </summary>
54+
void IDisposable.Dispose()
55+
{
56+
Dispose(disposing: true);
57+
GC.SuppressFinalize(this);
58+
}
59+
60+
/// <summary>
61+
/// Clean up of any leftover managed and unmanaged resources.
62+
/// </summary>
63+
protected abstract void Dispose(bool disposing);
64+
65+
}
66+
}

src/mscorlib/shared/System/Buffers/OwnedMemory.cs

Lines changed: 0 additions & 95 deletions
This file was deleted.

src/mscorlib/shared/System/IO/FileStreamCompletionSource.Win32.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,7 @@ private sealed class MemoryFileStreamCompletionSource : FileStreamCompletionSour
246246
internal MemoryFileStreamCompletionSource(FileStream stream, int numBufferedBytes, ReadOnlyMemory<byte> memory) :
247247
base(stream, numBufferedBytes, bytes: null) // this type handles the pinning, so null is passed for bytes
248248
{
249-
_handle = memory.Retain(pin: true);
249+
_handle = memory.Pin();
250250
}
251251

252252
internal override void ReleaseNativeResource()

0 commit comments

Comments
 (0)