_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

This commit is contained in:
2025-12-18 14:09:07 +02:00
parent e9e27b1e76
commit 0008435f1c

View File

@@ -2,7 +2,7 @@
#define USE_CONCURRENT_DICT
#define USE_GCHANDLE
//#define TRACK_HANDLES
#define TRACK_HANDLES
#if USE_NETCORE
using System;
@@ -368,10 +368,17 @@ namespace FlaxEngine.Interop
private static HashSet<IntPtr> _weakHandles = new HashSet<nint>();
private static ConcurrentDictionary<IntPtr, string> _handles = 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
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private ManagedHandle(IntPtr handle) => this.handle = GCHandle.FromIntPtr(handle);
//[MethodImpl(MethodImplOptions.AggressiveInlining)]
private ManagedHandle(object value, GCHandleType type) //=> handle = GCHandle.Alloc(value, type);
{
#if TRACK_HANDLES
@@ -394,6 +401,7 @@ namespace FlaxEngine.Interop
type = type;
_handles2.TryAdd((IntPtr)handle, value?.GetType().FullName ?? "");
}
Interlocked.Increment(ref _allocations);
#endif
}
#else
@@ -430,14 +438,25 @@ namespace FlaxEngine.Interop
{
handle = handle;
}
Interlocked.Increment(ref _deallocations);
#endif
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
public void Free()
{
@@ -485,22 +504,64 @@ namespace FlaxEngine.Interop
public static IntPtr ToIntPtr(ManagedHandle value) => value.handle;
#endif
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public override int GetHashCode() => handle.GetHashCode();
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public override bool Equals(object obj) => obj is ManagedHandle other && handle == other.handle;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool Equals(ManagedHandle other) => handle == other.handle;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
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;
#if USE_GCHANDLE
/// <summary>
/// A pool of shared managed handles used with short-lived temporary GCHandle allocations during interop.
/// </summary>
internal static class ManagedHandlePool
{
[ThreadStatic]
private static List<(bool InUse, ManagedHandle Handle)> _pool;
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