Skip to content

Commit cdcc528

Browse files
mkustermanncommit-bot@chromium.org
authored andcommitted
[vm] Add NativePort static extension to dart:ffi
This can be used in combination with `dart:ffi` to allow C code to post messages asynchronously back to Dart. Issue #38544 Change-Id: I0293337785a3555b4147e25f1a904f333da62c52 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/118565 Commit-Queue: Martin Kustermann <kustermann@google.com> Reviewed-by: Daco Harkes <dacoharkes@google.com> Reviewed-by: Lasse R.H. Nielsen <lrn@google.com> Reviewed-by: Ryan Macnak <rmacnak@google.com> Reviewed-by: Samir Jindel <sjindel@google.com>
1 parent 6b61050 commit cdcc528

File tree

9 files changed

+74
-0
lines changed

9 files changed

+74
-0
lines changed

sdk/lib/_internal/vm/lib/ffi_dynamic_library_patch.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
// the patches are applied.
77
import "dart:_internal" show patch;
88
import 'dart:typed_data';
9+
import 'dart:isolate';
910

1011
DynamicLibrary _open(String name) native "Ffi_dl_open";
1112
DynamicLibrary _processLibrary() native "Ffi_dl_processLibrary";

sdk/lib/_internal/vm/lib/ffi_native_type_patch.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
// the patches are applied.
77
import "dart:_internal" show patch;
88
import 'dart:typed_data';
9+
import 'dart:isolate';
910

1011
// NativeType is not private, because it is used in type arguments.
1112
// NativeType is abstract because it not used with const constructors in

sdk/lib/_internal/vm/lib/ffi_patch.dart

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
// the patches are applied.
77
import "dart:_internal" show patch;
88
import 'dart:typed_data';
9+
import 'dart:isolate';
910

1011
const Map<Type, int> _knownSizes = {
1112
Int8: 1,
@@ -442,3 +443,8 @@ extension StructPointer<T extends Struct> on Pointer<T> {
442443
@patch
443444
T operator [](int index) => _loadStruct(this, index);
444445
}
446+
447+
extension NativePort on SendPort {
448+
@patch
449+
int get nativePort native "SendPortImpl_get_id";
450+
}

sdk/lib/ffi/ffi.dart

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
library dart.ffi;
1616

1717
import 'dart:typed_data';
18+
import 'dart:isolate';
1819

1920
part "native_type.dart";
2021
part "annotations.dart";
@@ -609,3 +610,13 @@ extension StructPointer<T extends Struct> on Pointer<T> {
609610
/// the platform.
610611
external T operator [](int index);
611612
}
613+
614+
/// Extension to retrieve the native `Dart_Port` from a [SendPort].
615+
extension NativePort on SendPort {
616+
/// The native port of this [SendPort].
617+
///
618+
/// The returned native port can for example be used by C code to post
619+
/// messages to the connected [ReceivePort] via `Dart_PostCObject()` - see
620+
/// `dart_native_api.h`.
621+
external int get nativePort;
622+
}

sdk_nnbd/lib/_internal/vm/lib/ffi_dynamic_library_patch.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
// the patches are applied.
99
import "dart:_internal" show patch;
1010
import 'dart:typed_data';
11+
import 'dart:isolate';
1112

1213
DynamicLibrary _open(String name) native "Ffi_dl_open";
1314
DynamicLibrary _processLibrary() native "Ffi_dl_processLibrary";

sdk_nnbd/lib/_internal/vm/lib/ffi_native_type_patch.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
// the patches are applied.
99
import "dart:_internal" show patch;
1010
import 'dart:typed_data';
11+
import 'dart:isolate';
1112

1213
// NativeType is not private, because it is used in type arguments.
1314
// NativeType is abstract because it not used with const constructors in

sdk_nnbd/lib/_internal/vm/lib/ffi_patch.dart

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
// the patches are applied.
99
import "dart:_internal" show patch;
1010
import 'dart:typed_data';
11+
import 'dart:isolate';
1112

1213
const Map<Type, int> _knownSizes = {
1314
Int8: 1,
@@ -444,3 +445,8 @@ extension StructPointer<T extends Struct> on Pointer<T> {
444445
@patch
445446
T operator [](int index) => _loadStruct(this, index);
446447
}
448+
449+
extension NativePort on SendPort {
450+
@patch
451+
int get nativePort native "SendPortImpl_get_id";
452+
}

sdk_nnbd/lib/ffi/ffi.dart

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -611,3 +611,13 @@ extension StructPointer<T extends Struct> on Pointer<T> {
611611
/// the platform.
612612
external T operator [](int index);
613613
}
614+
615+
/// Extension to retrieve the native `Dart_Port` from a [SendPort].
616+
extension NativePort on SendPort {
617+
/// The native port of this [SendPort].
618+
///
619+
/// The returned native port can for example be used by C code to post
620+
/// messages to the connected [ReceivePort] via `Dart_PostCObject()` - see
621+
/// `dart_native_api.h`.
622+
external int get nativePort;
623+
}

tests/ffi/send_port_id_test.dart

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
import 'dart:async';
6+
import 'dart:ffi';
7+
import 'dart:isolate';
8+
9+
import 'package:expect/expect.dart';
10+
11+
typedef Dart_PostIntegerNFT = IntPtr Function(Int64 port, Int64 message);
12+
typedef Dart_PostIntegerFT = int Function(int port, int message);
13+
14+
main() async {
15+
const int message = 112344556677888;
16+
17+
final completer = Completer();
18+
19+
final receivePort = ReceivePort()
20+
..listen((receivedMessage) => completer.complete(receivedMessage));
21+
22+
final executableSymbols = DynamicLibrary.executable();
23+
24+
final postInteger =
25+
executableSymbols.lookupFunction<Dart_PostIntegerNFT, Dart_PostIntegerFT>(
26+
"Dart_PostInteger");
27+
28+
// Issue(dartbug.com/38545): The dart:ffi doesn't have a bool type yet.
29+
final bool success =
30+
postInteger(receivePort.sendPort.nativePort, message) != 0;
31+
Expect.isTrue(success);
32+
33+
final postedMessage = await completer.future;
34+
Expect.equals(message, postedMessage);
35+
36+
receivePort.close();
37+
}

0 commit comments

Comments
 (0)