Initial commit
This commit is contained in:
@@ -0,0 +1,52 @@
|
||||
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);
|
||||
}
|
||||
Reference in New Issue
Block a user