Skip to content

Dart with Rust: The efficient way to pass around big objects while following Rust's memory management and Dart's GC? #47323

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

Open
fzyzcjy opened this issue Sep 29, 2021 · 2 comments
Labels
area-vm Use area-vm for VM related issues, including code coverage, and the AOT and JIT backends.

Comments

@fzyzcjy
Copy link
Contributor

fzyzcjy commented Sep 29, 2021

Hi thanks for the wonderful langauge and Flutter! This question follows dart-lang/language#1862 , (because I follow @mraleph 's suggestion and decide to use Dart_PostCObject).

The problem setup: I have a Flutter app with main isolate (no more worker isolates). I have some Rust code computing big images and talk to Flutter/Dart via FFI. For example, a typical call is:

  • Flutter calls Rust's create_an_image()
  • Rust's create_an_image creates (for simplicity) a new thread, and let that thread to do heavy work of generating a big image (say, rust_worker_thread_create_an_image). But the create_an_image function returns immediately, thus Flutter will not be blocked, and we never need a worker isolate now.
  • After some time, rust_worker_thread_create_an_image() is finished. It uses Dart_PostCObject to post the image as an externalized typed data to Flutter, and Flutter can display it by receiving it in ReceivePort and give it to Image widget.

Now comes the problem: I want that big image to be manipulated later on again. Let's say, make it rotated by the angle given by the user via a text field in the UI (for simplicity).

Naive method is to copy the Uint8List to a region of memory allocated in Rust (suggested in dart-lang/language#1862), and pass it to Rust. But you see, we introduce one extra memory copy here.

Is it suggested (dart-lang/language#1862 (comment)) that I can use finalizers. But how should I do that with Rust's memory management system? And the mutability system - because when putting into an externalized typed data, it can be changed anywhere, while it cannot if we use pure Rust (at most one mutable borrow).

A naive way is that, if it is alive in externalized typed data (i.e. finalizer is not called yet), I should not use it in Rust. But this is silly, because Dart GC can happen very late after seconds, and before it is GCed, the finalizers will never be called, even if the pointer is already passed to Rust.

Thanks for any suggestions! I am not sure whether this should be asked here or on StackOverflow, so please tell me if I need to move.

@munificent munificent transferred this issue from dart-lang/language Sep 29, 2021
@munificent
Copy link
Member

Transferring this to the SDK repo since this is a question about the embedding API and not the language itself.

@lrhn lrhn added the area-vm Use area-vm for VM related issues, including code coverage, and the AOT and JIT backends. label Oct 5, 2021
@huang12zheng
Copy link

Can anyone tell me what changes have been made to this issue?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-vm Use area-vm for VM related issues, including code coverage, and the AOT and JIT backends.
Projects
None yet
Development

No branches or pull requests

4 participants