2 changed files with 58 additions and 53 deletions
@ -0,0 +1,57 @@ |
|||||
|
using System; |
||||
|
using System.Runtime.InteropServices; |
||||
|
|
||||
|
namespace Avalonia.Platform.Internal; |
||||
|
|
||||
|
internal class UnmanagedBlob : IUnmanagedBlob |
||||
|
{ |
||||
|
private IntPtr _address; |
||||
|
private readonly object _lock = new object(); |
||||
|
|
||||
|
public UnmanagedBlob(int size) |
||||
|
{ |
||||
|
try |
||||
|
{ |
||||
|
if (size <= 0) |
||||
|
throw new ArgumentException("Positive number required", nameof(size)); |
||||
|
_address = Marshal.AllocHGlobal(size); |
||||
|
GC.AddMemoryPressure(size); |
||||
|
Size = size; |
||||
|
} |
||||
|
catch |
||||
|
{ |
||||
|
GC.SuppressFinalize(this); |
||||
|
throw; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private void DoDispose() |
||||
|
{ |
||||
|
lock (_lock) |
||||
|
{ |
||||
|
if (!IsDisposed) |
||||
|
{ |
||||
|
Marshal.FreeHGlobal(_address); |
||||
|
GC.RemoveMemoryPressure(Size); |
||||
|
IsDisposed = true; |
||||
|
_address = IntPtr.Zero; |
||||
|
Size = 0; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public void Dispose() |
||||
|
{ |
||||
|
DoDispose(); |
||||
|
GC.SuppressFinalize(this); |
||||
|
} |
||||
|
|
||||
|
~UnmanagedBlob() |
||||
|
{ |
||||
|
DoDispose(); |
||||
|
} |
||||
|
|
||||
|
public IntPtr Address => IsDisposed ? throw new ObjectDisposedException("UnmanagedBlob") : _address; |
||||
|
public int Size { get; private set; } |
||||
|
public bool IsDisposed { get; private set; } |
||||
|
} |
||||
Loading…
Reference in new issue