_managed handle pool start
Some checks failed
Build Android / Game (Android, Release ARM64) (push) Has been cancelled
Build iOS / Game (iOS, Release ARM64) (push) Has been cancelled
Build Linux / Editor (Linux, Development x64) (push) Has been cancelled
Build Linux / Game (Linux, Release x64) (push) Has been cancelled
Build macOS / Editor (Mac, Development ARM64) (push) Has been cancelled
Build macOS / Game (Mac, Release ARM64) (push) Has been cancelled
Build Windows / Editor (Windows, Development x64) (push) Has been cancelled
Build Windows / Game (Windows, Release x64) (push) Has been cancelled
Cooker / Cook (Mac) (push) Has been cancelled
Tests / Tests (Linux) (push) Has been cancelled
Tests / Tests (Windows) (push) Has been cancelled
Some checks failed
Build Android / Game (Android, Release ARM64) (push) Has been cancelled
Build iOS / Game (iOS, Release ARM64) (push) Has been cancelled
Build Linux / Editor (Linux, Development x64) (push) Has been cancelled
Build Linux / Game (Linux, Release x64) (push) Has been cancelled
Build macOS / Editor (Mac, Development ARM64) (push) Has been cancelled
Build macOS / Game (Mac, Release ARM64) (push) Has been cancelled
Build Windows / Editor (Windows, Development x64) (push) Has been cancelled
Build Windows / Game (Windows, Release x64) (push) Has been cancelled
Cooker / Cook (Mac) (push) Has been cancelled
Tests / Tests (Linux) (push) Has been cancelled
Tests / Tests (Windows) (push) Has been cancelled
This commit is contained in:
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#define USE_CONCURRENT_DICT
|
#define USE_CONCURRENT_DICT
|
||||||
#define USE_GCHANDLE
|
#define USE_GCHANDLE
|
||||||
//#define TRACK_HANDLES
|
#define TRACK_HANDLES
|
||||||
|
|
||||||
#if USE_NETCORE
|
#if USE_NETCORE
|
||||||
using System;
|
using System;
|
||||||
@@ -368,10 +368,17 @@ namespace FlaxEngine.Interop
|
|||||||
private static HashSet<IntPtr> _weakHandles = new HashSet<nint>();
|
private static HashSet<IntPtr> _weakHandles = new HashSet<nint>();
|
||||||
private static ConcurrentDictionary<IntPtr, string> _handles = new();
|
private static ConcurrentDictionary<IntPtr, string> _handles = new();
|
||||||
private static ConcurrentDictionary<IntPtr, string> _handles2 = new();
|
private static ConcurrentDictionary<IntPtr, string> _handles2 = new();
|
||||||
|
private static long _allocations = 0;
|
||||||
|
private static long _deallocations = 0;
|
||||||
|
|
||||||
|
public static long Allocations => Interlocked.Read(ref _allocations);
|
||||||
|
public static long Deallocations => Interlocked.Read(ref _deallocations);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
private ManagedHandle(IntPtr handle) => this.handle = GCHandle.FromIntPtr(handle);
|
private ManagedHandle(IntPtr handle) => this.handle = GCHandle.FromIntPtr(handle);
|
||||||
|
|
||||||
|
//[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
private ManagedHandle(object value, GCHandleType type) //=> handle = GCHandle.Alloc(value, type);
|
private ManagedHandle(object value, GCHandleType type) //=> handle = GCHandle.Alloc(value, type);
|
||||||
{
|
{
|
||||||
#if TRACK_HANDLES
|
#if TRACK_HANDLES
|
||||||
@@ -394,6 +401,7 @@ namespace FlaxEngine.Interop
|
|||||||
type = type;
|
type = type;
|
||||||
_handles2.TryAdd((IntPtr)handle, value?.GetType().FullName ?? "");
|
_handles2.TryAdd((IntPtr)handle, value?.GetType().FullName ?? "");
|
||||||
}
|
}
|
||||||
|
Interlocked.Increment(ref _allocations);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
@@ -430,14 +438,25 @@ namespace FlaxEngine.Interop
|
|||||||
{
|
{
|
||||||
handle = handle;
|
handle = handle;
|
||||||
}
|
}
|
||||||
|
Interlocked.Increment(ref _deallocations);
|
||||||
#endif
|
#endif
|
||||||
handle.Free();
|
handle.Free();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public object Target => handle.Target;
|
public object Target
|
||||||
|
{
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
get => handle.Target;
|
||||||
|
|
||||||
public bool IsAllocated => handle.IsAllocated;
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
set => handle.Target = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsAllocated
|
||||||
|
{
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
get => handle.IsAllocated;
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
public void Free()
|
public void Free()
|
||||||
{
|
{
|
||||||
@@ -485,22 +504,64 @@ namespace FlaxEngine.Interop
|
|||||||
public static IntPtr ToIntPtr(ManagedHandle value) => value.handle;
|
public static IntPtr ToIntPtr(ManagedHandle value) => value.handle;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public override int GetHashCode() => handle.GetHashCode();
|
public override int GetHashCode() => handle.GetHashCode();
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public override bool Equals(object obj) => obj is ManagedHandle other && handle == other.handle;
|
public override bool Equals(object obj) => obj is ManagedHandle other && handle == other.handle;
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public bool Equals(ManagedHandle other) => handle == other.handle;
|
public bool Equals(ManagedHandle other) => handle == other.handle;
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static bool operator ==(ManagedHandle a, ManagedHandle b) => a.handle == b.handle;
|
public static bool operator ==(ManagedHandle a, ManagedHandle b) => a.handle == b.handle;
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static bool operator !=(ManagedHandle a, ManagedHandle b) => a.handle != b.handle;
|
public static bool operator !=(ManagedHandle a, ManagedHandle b) => a.handle != b.handle;
|
||||||
|
|
||||||
#if USE_GCHANDLE
|
#if USE_GCHANDLE
|
||||||
|
/// <summary>
|
||||||
|
/// A pool of shared managed handles used with short-lived temporary GCHandle allocations during interop.
|
||||||
|
/// </summary>
|
||||||
internal static class ManagedHandlePool
|
internal static class ManagedHandlePool
|
||||||
{
|
{
|
||||||
|
[ThreadStatic]
|
||||||
|
private static List<(bool InUse, ManagedHandle Handle)> _pool;
|
||||||
|
|
||||||
internal static void TryCollectWeakHandles(bool force = false)
|
internal static void TryCollectWeakHandles(bool force = false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal static ManagedHandle Rent()
|
||||||
|
{
|
||||||
|
foreach (ref var tuple in CollectionsMarshal.AsSpan(_pool))
|
||||||
|
{
|
||||||
|
if (tuple.InUse)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
tuple.InUse = true;
|
||||||
|
return tuple.Handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
var newTuple = (InUse: true, Array: new ManagedHandle());
|
||||||
|
_pool.Add(newTuple);
|
||||||
|
return newTuple.Array;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static void Return(ManagedHandle handle)
|
||||||
|
{
|
||||||
|
foreach (ref var tuple in CollectionsMarshal.AsSpan(_pool))
|
||||||
|
{
|
||||||
|
if (tuple.Handle != handle)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
tuple.InUse = false;
|
||||||
|
handle.Target = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new Exception("Tried to return non-pooled ManagedHandle");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user