Skip to content
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

Enable sharing JObjects across isolates #1060

Merged
merged 10 commits into from
Apr 2, 2024
Merged

Conversation

HosseinYousefi
Copy link
Member

@HosseinYousefi HosseinYousefi commented Mar 26, 2024

Closes #1054. Closes #981.

Approach:
We use a FinalizableHandle which is for an entire isolate group as opposed to a NativeFinalizer which belongs to a single isolate. This way we can use @pragma('vm:deeply-immutable') on JReference to share the reference object between multiple isolates while the finalizable handle takes care of the global reference deletion.

The guarantees we provide:

  • use-after-free will throw from Dart
  • use-on-isolate-b-after-free-on-isolate-a will throw from Dart
  • double-free will throw from Dart
  • free-on-isolate-b-after-free-on-isolate-a will throw from Dart

In general, if we're not eagerly freeing via .release(), things work.

@HosseinYousefi HosseinYousefi requested a review from dcharkes March 26, 2024 17:22
@HosseinYousefi HosseinYousefi changed the title Enable sharing JObjects across isolates Enable sharing JObjects across isolates Mar 26, 2024
Copy link

github-actions bot commented Mar 26, 2024

PR Health

Coverage ⚠️

Details
File Coverage
pkgs/jni/example/integration_test/on_device_jni_test.dart 💔 Not covered
pkgs/jni/lib/src/errors.dart 💔 Not covered
pkgs/jni/lib/src/jni.dart 💔 Not covered
pkgs/jni/lib/src/jobject.dart 💔 Not covered
pkgs/jni/lib/src/jreference.dart 💔 Not covered
pkgs/jni/lib/src/third_party/jni_bindings_generated.dart 💔 Not covered
pkgs/jnigen/example/kotlin_plugin/example/lib/main.dart 💔 Not covered
pkgs/jnigen/tool/generate_runtime_tests.dart 💔 Not covered

This check for test coverage is informational (issues shown here will not fail the PR).

This check can be disabled by tagging the PR with skip-coverage-check

License Headers ⚠️

Details
// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
Files
pkgs/jni/lib/src/third_party/jni_bindings_generated.dart
pkgs/jnigen/example/kotlin_plugin/example/lib/main.dart

All source files should start with a license header.

Unrelated files missing license headers
Files
pkgs/ffi/example/main.dart
pkgs/ffigen/example/libclang-example/generated_bindings.dart
pkgs/ffigen/example/objective_c/avf_audio_bindings.dart
pkgs/ffigen/example/shared_bindings/generate.dart
pkgs/ffigen/example/shared_bindings/lib/generated/a_gen.dart
pkgs/ffigen/example/shared_bindings/lib/generated/a_shared_b_gen.dart
pkgs/ffigen/example/shared_bindings/lib/generated/base_gen.dart
pkgs/ffigen/example/simple/generated_bindings.dart
pkgs/ffigen/example/swift/swift_api_bindings.dart
pkgs/ffigen/lib/src/config_provider/config_spec.dart
pkgs/ffigen/lib/src/header_parser/clang_bindings/clang_bindings.dart
pkgs/ffigen/test/collision_tests/expected_bindings/_expected_decl_decl_collision_bindings.dart
pkgs/ffigen/test/collision_tests/expected_bindings/_expected_decl_symbol_address_collision_bindings.dart
pkgs/ffigen/test/collision_tests/expected_bindings/_expected_decl_type_name_collision_bindings.dart
pkgs/ffigen/test/collision_tests/expected_bindings/_expected_reserved_keyword_collision_bindings.dart
pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_comment_markup_bindings.dart
pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_dart_handle_bindings.dart
pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_forward_decl_bindings.dart
pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_functions_bindings.dart
pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_imported_types_bindings.dart
pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_native_func_typedef_bindings.dart
pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_opaque_dependencies_bindings.dart
pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_packed_structs_bindings.dart
pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_regress_384_bindings.dart
pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_struct_fptr_fields_bindings.dart
pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_typedef_bindings.dart
pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_unions_bindings.dart
pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_varargs_bindings.dart
pkgs/ffigen/test/large_integration_tests/_expected_cjson_bindings.dart
pkgs/ffigen/test/large_integration_tests/_expected_libclang_bindings.dart
pkgs/ffigen/test/large_integration_tests/_expected_sqlite_bindings.dart
pkgs/ffigen/test/native_test/_expected_native_test_bindings.dart
pkgs/jni/lib/src/lang/jcharacter.dart
pkgs/jni/lib/src/third_party/generated_bindings.dart
pkgs/jni/lib/src/third_party/global_env_extensions.dart
pkgs/jnigen/android_test_runner/lib/main.dart
pkgs/jnigen/example/in_app_java/lib/android_utils.dart
pkgs/jnigen/example/kotlin_plugin/lib/kotlin_bindings.dart
pkgs/jnigen/example/kotlin_plugin/lib/kotlin_plugin.dart
pkgs/jnigen/example/pdfbox_plugin/lib/pdfbox_plugin.dart
pkgs/jnigen/example/pdfbox_plugin/lib/src/third_party/_init.dart
pkgs/jnigen/example/pdfbox_plugin/lib/src/third_party/org/apache/pdfbox/pdmodel/PDDocument.dart
pkgs/jnigen/example/pdfbox_plugin/lib/src/third_party/org/apache/pdfbox/pdmodel/PDDocumentInformation.dart
pkgs/jnigen/example/pdfbox_plugin/lib/src/third_party/org/apache/pdfbox/pdmodel/_package.dart
pkgs/jnigen/example/pdfbox_plugin/lib/src/third_party/org/apache/pdfbox/text/PDFTextStripper.dart
pkgs/jnigen/example/pdfbox_plugin/lib/src/third_party/org/apache/pdfbox/text/_package.dart
pkgs/jnigen/lib/src/bindings/descriptor.dart
pkgs/jnigen/lib/src/elements/elements.g.dart
pkgs/jnigen/test/jackson_core_test/third_party/c_based/dart_bindings/com/fasterxml/jackson/core/_package.dart
pkgs/jnigen/test/jackson_core_test/third_party/dart_only/dart_bindings/com/fasterxml/jackson/core/_package.dart
pkgs/jnigen/tool/command_runner.dart

This check can be disabled by tagging the PR with skip-license-check

Package publish validation ✔️

Details
Package Version Status
package:ffi 2.1.2 already published at pub.dev
package:ffigen 12.0.0-wip WIP (no publish necessary)
package:jni 0.8.0-wip WIP (no publish necessary)
package:jnigen 0.8.0-wip WIP (no publish necessary)
package:native_assets_builder 0.6.1 already published at pub.dev
package:native_assets_cli 0.5.4 already published at pub.dev
package:native_toolchain_c 0.4.1 already published at pub.dev

Documentation at https://github.com/dart-lang/ecosystem/wiki/Publishing-automation.

@HosseinYousefi HosseinYousefi force-pushed the share-jobjects-isolate branch from cd3fc3a to 15ecede Compare March 26, 2024 18:04
@coveralls
Copy link

coveralls commented Mar 26, 2024

Coverage Status

coverage: 92.168% (-5.2%) from 97.413%
when pulling 847988a on share-jobjects-isolate
into 555f66b on main.

@dcharkes
Copy link
Collaborator

dcharkes commented Mar 27, 2024

Could you add a PR description with the overall approach?

And document what we do guard against and what we don't guard against. (e.g. we don't guard against concurrently using in one isolate and deleting in another).

Copy link
Collaborator

@dcharkes dcharkes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to be clear on what kind of safety guarantees we provide.

use-after-free will throw from Dart
use-on-isolate-b-after-free-on-isolate-a will throw from Dart
double-free will throw from Dart
free-on-isolate-b-after-free-on-isolate-a will throw from Dart
concurrent-free-on-two-isolates will throw from Dart (if we use compare and swap)

concurrent-use-and-free will not throw from Dart. It will crash. Please open an issue to address this in a follow up PR and document why we don't address it in this PR.

pkgs/jni/src/internal.h Show resolved Hide resolved
pkgs/jni/lib/src/jni.dart Show resolved Hide resolved
pkgs/jni/lib/src/jreference.dart Show resolved Hide resolved
pkgs/jni/lib/src/jreference.dart Show resolved Hide resolved
Copy link
Collaborator

@dcharkes dcharkes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

pkgs/jni/CHANGELOG.md Show resolved Hide resolved
pkgs/jni/lib/src/jreference.dart Show resolved Hide resolved
pkgs/jni/lib/src/jni.dart Show resolved Hide resolved
@HosseinYousefi HosseinYousefi merged commit 179a177 into main Apr 2, 2024
25 checks passed
@HosseinYousefi HosseinYousefi deleted the share-jobjects-isolate branch April 2, 2024 18:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Enable sharing of JObjects across isolates ☂️ Refactor JObject hierarchy
3 participants