using System; using CeresSharp.Native; namespace CeresSharp.Native.SafeHandles; /// /// Safe handle for Ceres LossFunction. /// internal sealed class LossFunctionHandle : BaseSafeHandle { private volatile bool _ownedByProblem = false; private LossFunctionHandle() : base() { } private LossFunctionHandle(IntPtr handle, bool ownsHandle) : base(handle, ownsHandle) { } public static LossFunctionHandle Create(IntPtr handle) { if (handle == IntPtr.Zero) { throw new Exceptions.CeresException(Exceptions.CeresErrorCode.NullPointer, "Loss function handle is null"); } return new LossFunctionHandle(handle, true); } /// /// Marks this loss function as owned by a Problem. /// When owned by Problem, the native handle should NOT be freed here /// because Problem/Ceres will free it when Problem is destroyed. /// internal void MarkOwnedByProblem() => _ownedByProblem = true; protected override void ReleaseNativeHandle(IntPtr handle) { if (_ownedByProblem) { // Problem owns this loss function - Ceres will delete it when Problem is freed. // Do NOT free here to avoid double-free. return; } // Standalone loss function - we must free it ourselves CeresNative.ceres_wrapper_free_loss_function(handle); } }