Class NativeHandle
A SafeHandle over a native pointer whose release function is supplied at construction, so the handle is always released exactly once even across finalization races.
public sealed class NativeHandle : SafeHandle, IDisposable
- Inheritance
-
NativeHandle
- Implements
- Inherited Members
Remarks
The helper-math capabilities expose a family of handles that differ only in
which *_free function releases them, so one handle type carrying that
function serves them all.
A handle behind an object with asynchronous members is created serialized: its calls run one at a time, so a send issued while a receive is waiting runs once the receive returns, rather than reaching the native object alongside it. A call that waits its turn through UseAsync<TResult>(Func<nint, TResult>) holds no thread while it waits.
Constructors
NativeHandle(nint, Action<nint>, bool)
Wraps a non-null native pointer with the function that frees it.
public NativeHandle(nint handle, Action<nint> release, bool serialized = false)
Parameters
handlenintThe pointer returned by a native constructor.
releaseAction<nint>The matching native release function.
serializedboolRun the calls on this handle one at a time.
Properties
IsInvalid
When overridden in a derived class, gets a value indicating whether the handle value is invalid.
public override bool IsInvalid { get; }
Property Value
Methods
Create(nint, Action<nint>, string, bool)
Creates a wrapper, throwing when the native constructor returned null.
public static NativeHandle Create(nint handle, Action<nint> release, string what, bool serialized = false)
Parameters
handlenintThe pointer returned by a native constructor.
releaseAction<nint>The matching native release function.
whatstringWhat was being created, for the exception message.
serializedboolRun the calls on this handle one at a time.
Returns
- NativeHandle
The wrapped handle.
Exceptions
- PamojaException
The native constructor returned null.
Lease()
Holds the handle open until the lease is disposed.
public NativeLease Lease()
Returns
- NativeLease
The lease, whose pointer stays valid until it is disposed.
Remarks
A native call that takes a span cannot go through Use<TResult>(Func<nint, TResult>), since a
lambda cannot capture one, so it leases the pointer instead:
using NativeLease lease = handle.Lease();. On a serialized handle the lease
holds the handle's turn as well.
Exceptions
- ObjectDisposedException
The handle was already released.
LendAsync<TResult>(Func<nint, Task<TResult>>)
Lends the pointer to asynchronous work, such as a call on another handle that takes this one as an argument, holding the handle open until the work ends.
public Task<TResult> LendAsync<TResult>(Func<nint, Task<TResult>> work)
Parameters
Returns
- Task<TResult>
Whatever the work produced.
Type Parameters
TResultThe value the work produces.
ReleaseHandle()
When overridden in a derived class, executes the code required to free the handle.
protected override bool ReleaseHandle()
Returns
- bool
true if the handle is released successfully; otherwise, in the event of a catastrophic failure, false. In this case, it generates a releaseHandleFailed Managed Debugging Assistant.
Take(string)
Hands the pointer to a native call that takes ownership of it.
public nint Take(string busy)
Parameters
busystringThe message for a handle with a call running.
Returns
- nint
The pointer, which the caller now owns.
Remarks
This handle never releases the pointer afterwards. A call still running on a serialized handle is using the native object, so taking it then throws rather than giving away memory that call is still reading.
Exceptions
- PamojaException
A call on this handle is still running.
Use(Action<nint>)
Runs a native call that returns nothing, holding the handle open.
public void Use(Action<nint> call)
Parameters
UseAsync(Action<nint>)
Runs a native call that returns nothing on the thread pool, holding the handle open.
public Task UseAsync(Action<nint> call)
Parameters
Returns
- Task
A task that completes when the call has returned.
UseAsync<TResult>(Func<nint, TResult>)
Runs a native call on the thread pool, holding the handle open.
public Task<TResult> UseAsync<TResult>(Func<nint, TResult> call)
Parameters
Returns
- Task<TResult>
Whatever the native call returned.
Type Parameters
TResultThe value the native call returns.
Remarks
On a serialized handle the call first waits, without holding a thread, for any call already running on it.
UseTry<TValue>(NativeTry<TValue>)
Runs a native call that answers "maybe", holding the handle open, and maps its bool-plus-out-parameter shape onto a nullable value.
public TValue? UseTry<TValue>(NativeTry<TValue> call) where TValue : struct
Parameters
callNativeTry<TValue>The native call to make.
Returns
- TValue?
The value the call produced, or
nullwhen it produced none.
Type Parameters
TValueThe value the native call may produce.
Use<TResult>(Func<nint, TResult>)
Runs a native call that returns a value, holding the handle open.
public TResult Use<TResult>(Func<nint, TResult> call)
Parameters
Returns
- TResult
Whatever the native call returned.
Type Parameters
TResultThe value the native call returns.