using System; using System.Runtime.InteropServices; using Microsoft.Win32.SafeHandles; namespace CeresSharp.Native.SafeHandles; /// /// Base class for all Ceres native resource handles. /// 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; } } /// /// Releases the native handle. Must be implemented by derived classes. /// protected abstract void ReleaseNativeHandle(IntPtr handle); }