53 lines
1.6 KiB
C#
53 lines
1.6 KiB
C#
using System;
|
|
using System.Runtime.InteropServices;
|
|
using Microsoft.Win32.SafeHandles;
|
|
|
|
namespace CeresSharp.Native.SafeHandles;
|
|
|
|
/// <summary>
|
|
/// Base class for all Ceres native resource handles.
|
|
/// </summary>
|
|
public abstract class BaseSafeHandle : SafeHandleZeroOrMinusOneIsInvalid
|
|
{
|
|
protected BaseSafeHandle() : base(true)
|
|
{
|
|
}
|
|
|
|
protected BaseSafeHandle(IntPtr handle, bool ownsHandle) : base(ownsHandle)
|
|
{
|
|
SetHandle(handle);
|
|
}
|
|
|
|
private volatile bool _released = false;
|
|
|
|
protected override bool ReleaseHandle()
|
|
{
|
|
// Prevent double-free by checking if already released
|
|
// Use volatile read/write for thread safety in finalizer
|
|
if (_released || IsInvalid)
|
|
return true; // Already released or invalid
|
|
|
|
try
|
|
{
|
|
// Add try-catch to prevent crash in finalizer thread
|
|
// If native handle is already freed or invalid, this will fail gracefully
|
|
ReleaseNativeHandle(handle);
|
|
_released = true;
|
|
return true;
|
|
}
|
|
catch
|
|
{
|
|
// Ignore errors in finalizer - native handle may already be freed
|
|
// Mark as released to prevent retry
|
|
_released = true;
|
|
// Return true to indicate handle was "released" (even if it failed)
|
|
return true;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Releases the native handle. Must be implemented by derived classes.
|
|
/// </summary>
|
|
protected abstract void ReleaseNativeHandle(IntPtr handle);
|
|
}
|