-
Notifications
You must be signed in to change notification settings - Fork 51
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[ffigen] ObjCBlock.listener
refcounting issues
#835
Comments
Since ffigen added support for [`NativeCallable.listener`](https://api.flutter.dev/flutter/dart-ffi/NativeCallable/NativeCallable.listener.html) to its ObjC bindings, this example can be simplified. We can replace the `Dart_Port` logic with `ObjCBlock.listener`, which lets us get rid of most of the native code. We still need a small bit of native code to `retain` a reference to the callback's arguments before invoking the listener, otherwise the arguments may be ref counted and deleted before the Dart side of the callback is invoked. See dart-lang/native#835
Right, so the problem this is solving is that we don't call retain on the temp isolate that does argument marshalling, but we do the retain calls on the target Dart isolate, which might be arbitrarily delayed. I see multiple solutions to this issue:
Option 3 currently has the drawback that the users need to manually include that generated native code in their build. In the future, once we have native assets, users will need to write a build hook that refers to generated files (likely some trivial call to a helper in package:objc). The downside of option 3 is also that it is not a general solution. @HosseinYousefi How do we deal with this in JNIgen? When is the JavaGlobalReference constructed in callbacks via native ports? |
Also, if increasing the refcount in native code or on the marshaller isolate. How do we ensure the refcount is decreased if the message is never delivered to the target isolate?
Another alternative not involving isolate independent code:
|
We block and clean up the global references after invocation. |
Right, we don't have |
From an offline discussion with @mkustermann @liamappelbe et al. Option:
|
ObjCBlock.listener
lets ObjC code invoke Dart callbacks that live in other isolates. If they pass an object arg, it's possible that it gets refcounted and destroyed before the Dart callback runs (the Dart code calls retain, but it may be too late). So while these listener callbacks let us get rid of a lot ofNativePort
boilerplate, they don't totally eliminate the need for native code.These trampolines are super simple and can be automatically generated by ffigen. But automatically compiling them relies on native_assets.
The text was updated successfully, but these errors were encountered: