2

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 = this@Resource.nativePtr

        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.)

user3840170
  • 26,597
  • 4
  • 30
  • 62
  • OpenJDK’s implementation of `Cleaner` hands out `Cleanable`s that simply are `PhantomReference`s, on which one can simply invoke `clear` to disown them: . And it’s even used internally: . But it doesn’t seem to be anywhere in the public API. – user3840170 May 02 '21 at 13:19
  • I find it a little hard to follow what is asked here. Am I right to say that conditionally you don't want the cleanable.run() to actually invoke the disposeResource() function? Because if so... then that simply needs to be made actually conditional, a simply boolean flag would do it. – Gimby Jul 26 '21 at 12:21
  • @Gimby Yes, pretty much. I want to do the sort of thing that in C++ is accomplished by [`std::unique_ptr::release`](https://en.cppreference.com/w/cpp/memory/unique_ptr/release). What’s the JVM equivalent? – user3840170 Jul 26 '21 at 13:06

0 Answers0