jhugman / uniffi-bindgen-react-native

A uniffi bindings generator for calling Rust from react-native
https://jhugman.github.io/uniffi-bindgen-react-native/
Other
14 stars 3 forks source link

Add hooks into HostObject destructors #46

Closed jhugman closed 2 months ago

jhugman commented 3 months ago

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 Rust drop 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:

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.

The situation will only really get better when React Native/Hermes supports a robust FinalizationRegistry implementation.