How can I release ownership of a resource managed by a Cleaner?

264 views Asked by At

Suppose I have a wrapper object like this:

private val CLEANER = java.lang.ref.Cleaner.create()

internal typealias Ptr = Long
private external fun acquireResource(): Ptr
private external fun disposeResource(nativePtr: Ptr)

/* ... */

class Resource private constructor (private val nativePtr: Ptr):
    Closeable, AutoCloseable
{
    companion object {
        fun create(): Resource {
            return Resource(acquireResource())
        }
    }

    private val cleanable = CLEANER.register(this, object: Runnable {
        private val nativePtr = [email protected]

        override fun run() {
            disposeResource(nativePtr)
        }
    })

    override fun close() {
        cleanable.clean()
    }

    /* ... */
}

Now suppose I want to write a method internal fun release(): Ptr that makes the Resource give up ownership on nativePtr and then return it: in other words, when the Resource on which I called release is garbage-collected, its nativePtr pointer should not be disposed. (I intend that the Resource object should not be used after release is called, though I don’t see any way to enforce this.) This would allow me to pass the Ptr to an API that will manage its lifetime from then on.

How can I write release, preferably in an atomic/thread-safe manner? Is it even compatible with Cleaner?

(In other words, I am looking for an API equivalent to JavaScript’s FinalizationRegistry.prototype.unregister.)

0

There are 0 answers