Files
DotNetAlpm/SafeDatabaseHandle.cs
2020-04-27 12:34:56 -04:00

53 lines
1.6 KiB
C#

using System;
using System.Runtime.CompilerServices;
using System.Runtime.ConstrainedExecution;
using System.Runtime.InteropServices;
namespace Foodsoft.Alpm
{
internal sealed class SafeDatabaseHandle : SafeHandle
{
internal SafeAlpmHandle SafeAlpmHandle
{
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
[PrePrepareMethod]
get;
} = null!; // we always throw in the constructor on failure
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
[PrePrepareMethod]
internal SafeDatabaseHandle(IntPtr dbPtr, SafeAlpmHandle safeAlpmHandle)
: base(IntPtr.Zero, true)
{
var success = false;
RuntimeHelpers.PrepareConstrainedRegions();
try { }
finally
{
safeAlpmHandle.DangerousAddRef(ref success);
if (success)
{
SafeAlpmHandle = safeAlpmHandle;
handle = dbPtr;
}
}
if (!success) throw new ObjectDisposedException(GetType().FullName);
}
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail), PrePrepareMethod]
protected override bool ReleaseHandle()
{
var ret = alpm.alpm_db_unregister(handle) == 0;
SafeAlpmHandle.DangerousRelease();
return ret;
}
public override bool IsInvalid
{
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success), PrePrepareMethod]
get => handle == IntPtr.Zero;
}
}
}