Class NativeResourceHandle

java.lang.Object
ai.tegmentum.wasmtime4j.panama.util.NativeResourceHandle
All Implemented Interfaces:
AutoCloseable

public final class NativeResourceHandle extends Object implements AutoCloseable
Thread-safe resource lifecycle handle using composition.

This class encapsulates the closed-flag lifecycle pattern used across all Panama FFI classes. Each Panama class holds a NativeResourceHandle as a field and delegates close/ensureNotClosed to it, replacing the duplicated volatile boolean + ensureNotClosed boilerplate.

Key features:

Safety net pattern: When using the Cleaner safety net, the safetyNetAction must NOT capture a reference to the owning object. Capture only extracted local values (e.g., a MemorySegment field). Otherwise the Cleaner prevents GC of the owning object and the safety net never fires.

Since:
1.0.0
  • Constructor Details

    • NativeResourceHandle

      public NativeResourceHandle(String resourceType, NativeResourceHandle.CleanupAction closeAction, Object safetyNetOwner, Runnable safetyNetAction)
      Creates a resource handle with a Cleaner safety net.

      CRITICAL: The safetyNetAction Runnable must NOT capture a reference to the owning object. Capture only extracted primitive values or handles. If the Runnable captures this (the owning object), the Cleaner will prevent the object from being GC'd and the safety net will never fire.

      Parameters:
      resourceType - human-readable resource type for logging and error messages
      closeAction - the cleanup action to run on explicit close
      safetyNetOwner - the object whose GC triggers the safety net (typically the owning object)
      safetyNetAction - cleanup to run if the owner is GC'd without close (must not capture owner)
    • NativeResourceHandle

      public NativeResourceHandle(String resourceType, NativeResourceHandle.CleanupAction closeAction)
      Creates a resource handle without a Cleaner safety net.

      Use this constructor for resources that don't hold native pointers directly, or where the Arena already provides cleanup guarantees.

      Parameters:
      resourceType - human-readable resource type for logging and error messages
      closeAction - the cleanup action to run on explicit close
  • Method Details

    • ensureNotClosed

      public void ensureNotClosed()
      Ensures the resource is not closed.

      Warning: This method does NOT acquire the close lock. For thread-safe operation guarding, use beginOperation() / endOperation() instead to prevent use-after-free race conditions with concurrent close() calls.

      Throws:
      IllegalStateException - if the resource has been closed
    • beginOperation

      public void beginOperation()
      Begins a guarded operation by acquiring the read lock and verifying the resource is not closed.

      Every call to beginOperation() must be paired with endOperation() in a finally block.

      Throws:
      IllegalStateException - if the resource has been closed
    • endOperation

      public void endOperation()
      Ends a guarded operation by releasing the read lock.

      Must be called in a finally block after beginOperation().

    • tryBeginOperation

      public boolean tryBeginOperation()
      Attempts to begin a guarded operation. Returns false if the resource is closed, without throwing. If this returns true, the caller must call endOperation() in a finally block.
      Returns:
      true if the operation can proceed (lock acquired), false if closed
    • isClosed

      public boolean isClosed()
      Checks if this resource has been closed.
      Returns:
      true if the resource is closed, false otherwise
    • close

      public void close()
      Closes the resource. Thread-safe and idempotent — only the first call executes the cleanup action. Subsequent calls are no-ops. Acquires the write lock to ensure no in-flight operations are using the native handle when it is freed.
      Specified by:
      close in interface AutoCloseable