LibUv Networking (#65)
This commit is contained in:
parent
ec6629fbe9
commit
5e2be2d7b6
69 changed files with 5612 additions and 586 deletions
74
Projects/Server/Buffers/MemoryPoolSlab.cs
Normal file
74
Projects/Server/Buffers/MemoryPoolSlab.cs
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace System.Buffers
|
||||
{
|
||||
/// <summary>
|
||||
/// Slab tracking object used by the byte buffer memory pool. A slab is a large allocation which is divided into smaller blocks. The
|
||||
/// individual blocks are then treated as independent array segments.
|
||||
/// </summary>
|
||||
public class MemoryPoolSlab : IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// This handle pins the managed array in memory until the slab is disposed. This prevents it from being
|
||||
/// relocated and enables any subsections of the array to be used as native memory pointers to P/Invoked API calls.
|
||||
/// </summary>
|
||||
private GCHandle _gcHandle;
|
||||
private bool _isDisposed;
|
||||
|
||||
public MemoryPoolSlab(byte[] data)
|
||||
{
|
||||
Array = data;
|
||||
_gcHandle = GCHandle.Alloc(data, GCHandleType.Pinned);
|
||||
NativePointer = _gcHandle.AddrOfPinnedObject();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// True as long as the blocks from this slab are to be considered returnable to the pool. In order to shrink the
|
||||
/// memory pool size an entire slab must be removed. That is done by (1) setting IsActive to false and removing the
|
||||
/// slab from the pool's _slabs collection, (2) as each block currently in use is Return()ed to the pool it will
|
||||
/// be allowed to be garbage collected rather than re-pooled, and (3) when all block tracking objects are garbage
|
||||
/// collected and the slab is no longer references the slab will be garbage collected and the memory unpinned will
|
||||
/// be unpinned by the slab's Dispose.
|
||||
/// </summary>
|
||||
public bool IsActive => !_isDisposed;
|
||||
|
||||
public IntPtr NativePointer { get; private set; }
|
||||
|
||||
public byte[] Array { get; private set; }
|
||||
|
||||
public static MemoryPoolSlab Create(int length)
|
||||
{
|
||||
// allocate and pin requested memory length
|
||||
var array = new byte[length];
|
||||
|
||||
// allocate and return slab tracking object
|
||||
return new MemoryPoolSlab(array);
|
||||
}
|
||||
|
||||
protected void Dispose(bool disposing)
|
||||
{
|
||||
if (_isDisposed) return;
|
||||
|
||||
_isDisposed = true;
|
||||
|
||||
Array = null;
|
||||
NativePointer = IntPtr.Zero;;
|
||||
|
||||
if (_gcHandle.IsAllocated) _gcHandle.Free();
|
||||
}
|
||||
|
||||
~MemoryPoolSlab()
|
||||
{
|
||||
Dispose(false);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue