[ffi/isolate_group] Move IsolateGroupBound callbacks from isolate to isolate group.

This allows creation of isolategroup-bound callbacks when isolate is not available. For example, to support proposed Isolate::onEvent/Isolate::handleEvent api https://github.com/dart-lang/language/blob/main/working/333%20-%20shared%20memory%20multithreading/shared_native_memory.md#additional-isolate-apis.

BUG=https://github.com/dart-lang/sdk/issues/63291
TEST=isolate_group_bound_callback_test

CoreLibraryReviewExempt: vm ffi-specific comments changes
Change-Id: I9a757a39ba8e152db64f59a66d337ca672103277
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/499661
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Commit-Queue: Alexander Aprelev <aam@google.com>
This commit is contained in:
Alexander Aprelev
2026-05-05 08:37:06 -07:00
committed by dart-scoped@luci-project-accounts.iam.gserviceaccount.com
parent b10062cbbf
commit 00cda4d60f
7 changed files with 82 additions and 52 deletions
+31 -14
View File
@@ -203,6 +203,11 @@ external void _deleteNativeCallable<NS extends NativeFunction>(
Pointer<NS> pointer,
);
@pragma("vm:external-name", "Ffi_deleteIsolateGroupNativeCallable")
external void _deleteIsolateGroupNativeCallable<NS extends NativeFunction>(
Pointer<NS> pointer,
);
@pragma("vm:external-name", "Ffi_updateNativeCallableKeepIsolateAliveCounter")
external void _updateNativeCallableKeepIsolateAliveCounter<
NS extends NativeFunction
@@ -348,28 +353,40 @@ final class _NativeCallableListener<T extends Function>
}
final class _NativeCallableIsolateGroupBound<T extends Function>
extends _NativeCallableBase<T> {
bool _isKeepingIsolateAlive = true;
implements NativeCallable<T> {
Pointer<NativeFunction<T>> _pointer;
_NativeCallableIsolateGroupBound(super._pointer) {
_updateNativeCallableKeepIsolateAliveCounter(1);
_NativeCallableIsolateGroupBound(this._pointer);
@override
Pointer<NativeFunction<T>> get nativeFunction {
if (_isClosed) {
throw StateError("NativeCallable is already closed.");
}
return _pointer;
}
@override
void _close() {
_keepIsolateAlive = false;
}
@override
void set _keepIsolateAlive(bool value) {
if (_isKeepingIsolateAlive != value) {
_isKeepingIsolateAlive = value;
_updateNativeCallableKeepIsolateAliveCounter(value ? 1 : -1);
void close() {
if (!_isClosed) {
_deleteIsolateGroupNativeCallable(_pointer);
_pointer = nullptr;
}
}
@override
bool get _keepIsolateAlive => _isKeepingIsolateAlive;
void set keepIsolateAlive(bool value) {
if (value) {
throw ArgumentError(
"IsolateGroupBound callables can not keep isolate alive",
);
}
}
@override
bool get keepIsolateAlive => false;
bool get _isClosed => _pointer == nullptr;
}
@patch
+5 -2
View File
@@ -414,8 +414,7 @@ abstract final class NativeCallable<T extends Function> {
/// _trivially shareable_.
///
/// This callback must be [close]d when it is no longer
/// needed. An [Isolate] that created the callback will
/// be kept alive until [close] is called.
/// needed.
///
/// After [NativeCallable.close] is called, invoking
/// the [nativeFunction] from native code will cause
@@ -522,6 +521,10 @@ abstract final class NativeCallable<T extends Function> {
/// By default, [NativeCallable]s keep the [Isolate] that created them alive
/// until [close] is called. If [keepIsolateAlive] is set to `false`, the
/// isolate may exit even if the [NativeCallable] isn't closed.
///
/// Note: IsolateGroupBound-callbacks are not associated with an [Isolate],
/// so won't keep an isolate alive. Attempts to set [keepIsolateAlive] to
/// true, will throw.
external bool get keepIsolateAlive;
external set keepIsolateAlive(bool value);
}