Generally speaking, when dealing with native resources, it is
recommended to free the native resource explicitly when you are done
with it, because garbage collection is unpredictable and should not be
relied on for freeing native resources timely."
From the HostObject's destructor docs:
The C++ object's dtor will be called when the GC finalizes this
object. (This may be as late as when the Runtime is shut down.)
You have no control over which thread it is called on. This will
be called from inside the GC…
For this reason, the uniffiDestroy method is left in place for now: if you absolutely need to drop a Rust peer object, then you should call the uniffiDestroy method of the correspond JS object.
From the integration tests alone, it is difficult to show that this is working; they are too short-lived for the Runtime to be still running and garbage collection to have taken place.
However, the test_callbacks.ts did cause an ungraceful shutdown when the destructor called into Rust which then called back into JS– which had already been killed.
Fixes #10 .
According to The Big O of Code Reviews, this is a O(n) change.
This PR adds C++ destructor hooks from uniffi
interface
objects, to call the corresponding Rustdrop
methods.The impedance mismatch between a GC'd language and an RAII language means that one is a leaky abstraction for the other.
From https://github.com/facebook/hermes/issues/982#issuecomment-1771325667:
From the HostObject's destructor docs:
For this reason, the
uniffiDestroy
method is left in place for now: if you absolutely need to drop a Rust peer object, then you should call theuniffiDestroy
method of the correspond JS object.From the integration tests alone, it is difficult to show that this is working; they are too short-lived for the Runtime to be still running and garbage collection to have taken place.
However, the
test_callbacks.ts
did cause an ungraceful shutdown when the destructor called into Rust which then called back into JS– which had already been killed.The situation will only really get better when React Native/Hermes supports a robust
FinalizationRegistry
implementation.