Created
October 23, 2017 23:50
-
-
Save svick/1ddc3e59d1d9bc12c809064973b1d523 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// based on https://github.com/dotnet/corefx/blob/389d7ee/src/System.Memory/tests/Memory/CustomMemoryForTest.cs | |
unsafe class HGlobalMemory : OwnedMemory<byte> | |
{ | |
private bool _disposed; | |
private int _referenceCount; | |
private byte* _buffer; | |
private int _length; | |
public HGlobalMemory(int length) | |
{ | |
_buffer = (byte*)Marshal.AllocHGlobal(length); | |
_length = length; | |
} | |
public override int Length => _length; | |
public override bool IsDisposed => _disposed; | |
protected override bool IsRetained => _referenceCount > 0; | |
public override Span<byte> AsSpan() | |
{ | |
if (IsDisposed) | |
throw new ObjectDisposedException(nameof(HGlobalMemory)); | |
return new Span<byte>(_buffer, _length); | |
} | |
public override MemoryHandle Pin() | |
{ | |
Retain(); | |
return new MemoryHandle(this, _buffer); | |
} | |
protected override bool TryGetArray(out ArraySegment<byte> arraySegment) | |
{ | |
if (IsDisposed) | |
throw new ObjectDisposedException(nameof(HGlobalMemory)); | |
arraySegment = default; | |
return false; | |
} | |
protected override void Dispose(bool disposing) | |
{ | |
if (_disposed) | |
return; | |
Marshal.FreeHGlobal((IntPtr)_buffer); | |
_buffer = null; | |
if (disposing) | |
GC.SuppressFinalize(this); | |
_disposed = true; | |
} | |
~HGlobalMemory() => Dispose(false); | |
public override void Retain() | |
{ | |
if (IsDisposed) | |
throw new ObjectDisposedException(nameof(HGlobalMemory)); | |
Interlocked.Increment(ref _referenceCount); | |
} | |
public override bool Release() | |
{ | |
int newRefCount = Interlocked.Decrement(ref _referenceCount); | |
if (newRefCount < 0) | |
throw new InvalidOperationException(); | |
return newRefCount != 0; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment