mirror of
https://github.com/dart-lang/sdk
synced 2024-09-16 04:57:43 +00:00
[vm/ffi] Clarify DynamicLibrary.open behavior
Both dlopen and LoadLibrary have caching behavior and only load the dynamic library once into the DartVM, even with multiple isolates. Change-Id: If16791baf28706c61acb1ecdae668485b264a373 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/156682 Commit-Queue: Daco Harkes <dacoharkes@google.com> Reviewed-by: Aske Simon Christensen <askesc@google.com>
This commit is contained in:
parent
d7feab5aaa
commit
9871331450
|
@ -38,6 +38,16 @@ namespace dart {
|
|||
// Note: If this interface is changed please also update
|
||||
// sdk/runtime/tools/dartfuzz/ffiapi.dart
|
||||
|
||||
int32_t globalVar;
|
||||
|
||||
DART_EXPORT void SetGlobalVar(int32_t v) {
|
||||
globalVar = v;
|
||||
}
|
||||
|
||||
DART_EXPORT int32_t GetGlobalVar() {
|
||||
return globalVar;
|
||||
}
|
||||
|
||||
// Sums two ints and adds 42.
|
||||
// Simple function to test trampolines.
|
||||
// Also used for testing argument exception on passing null instead of a Dart
|
||||
|
|
|
@ -20,6 +20,10 @@ class DynamicLibrary {
|
|||
/// Loads a dynamic library file with local visibility.
|
||||
///
|
||||
/// Throws an [ArgumentError] if loading the dynamic library fails.
|
||||
///
|
||||
/// Calling this function multiple times, even in different isolates, returns
|
||||
/// objects which are equal but not identical. The underlying library is only
|
||||
/// loaded once into the DartVM by the OS.
|
||||
external factory DynamicLibrary.open(String name);
|
||||
|
||||
/// Looks up a symbol in the [DynamicLibrary] and returns its address in
|
||||
|
|
41
tests/ffi/dylib_isolates_test.dart
Normal file
41
tests/ffi/dylib_isolates_test.dart
Normal file
|
@ -0,0 +1,41 @@
|
|||
// Copyright (c) 2020, 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.
|
||||
//
|
||||
// Test for DynamicLibrary.open behavior on multiple isolates.
|
||||
//
|
||||
// SharedObjects=ffi_test_functions
|
||||
|
||||
import 'dart:ffi';
|
||||
import 'dart:isolate';
|
||||
|
||||
import "package:expect/expect.dart";
|
||||
|
||||
import 'dylib_utils.dart';
|
||||
|
||||
void main() async {
|
||||
final dl = dlopenPlatformSpecific('ffi_test_functions');
|
||||
final dl2 = dlopenPlatformSpecific('ffi_test_functions');
|
||||
Expect.equals(dl, dl2);
|
||||
Expect.isFalse(identical(dl, dl2));
|
||||
|
||||
final setGlobalVar = dl
|
||||
.lookupFunction<Void Function(Int32), void Function(int)>('SetGlobalVar');
|
||||
final getGlobalVar =
|
||||
dl.lookupFunction<Int32 Function(), int Function()>('GetGlobalVar');
|
||||
setGlobalVar(123);
|
||||
Expect.equals(123, getGlobalVar());
|
||||
|
||||
final receivePort = ReceivePort();
|
||||
Isolate.spawn(secondIsolateMain, receivePort.sendPort);
|
||||
await receivePort.first;
|
||||
Expect.equals(42, getGlobalVar());
|
||||
}
|
||||
|
||||
void secondIsolateMain(SendPort sendPort) {
|
||||
final dl = dlopenPlatformSpecific('ffi_test_functions');
|
||||
final setGlobalVar = dl
|
||||
.lookupFunction<Void Function(Int32), void Function(int)>('SetGlobalVar');
|
||||
setGlobalVar(42);
|
||||
sendPort.send('done');
|
||||
}
|
41
tests/ffi_2/dylib_isolates_test.dart
Normal file
41
tests/ffi_2/dylib_isolates_test.dart
Normal file
|
@ -0,0 +1,41 @@
|
|||
// Copyright (c) 2020, 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.
|
||||
//
|
||||
// Test for DynamicLibrary.open behavior on multiple isolates.
|
||||
//
|
||||
// SharedObjects=ffi_test_functions
|
||||
|
||||
import 'dart:ffi';
|
||||
import 'dart:isolate';
|
||||
|
||||
import "package:expect/expect.dart";
|
||||
|
||||
import 'dylib_utils.dart';
|
||||
|
||||
void main() async {
|
||||
final dl = dlopenPlatformSpecific('ffi_test_functions');
|
||||
final dl2 = dlopenPlatformSpecific('ffi_test_functions');
|
||||
Expect.equals(dl, dl2);
|
||||
Expect.isFalse(identical(dl, dl2));
|
||||
|
||||
final setGlobalVar = dl
|
||||
.lookupFunction<Void Function(Int32), void Function(int)>('SetGlobalVar');
|
||||
final getGlobalVar =
|
||||
dl.lookupFunction<Int32 Function(), int Function()>('GetGlobalVar');
|
||||
setGlobalVar(123);
|
||||
Expect.equals(123, getGlobalVar());
|
||||
|
||||
final receivePort = ReceivePort();
|
||||
Isolate.spawn(secondIsolateMain, receivePort.sendPort);
|
||||
await receivePort.first;
|
||||
Expect.equals(42, getGlobalVar());
|
||||
}
|
||||
|
||||
void secondIsolateMain(SendPort sendPort) {
|
||||
final dl = dlopenPlatformSpecific('ffi_test_functions');
|
||||
final setGlobalVar = dl
|
||||
.lookupFunction<Void Function(Int32), void Function(int)>('SetGlobalVar');
|
||||
setGlobalVar(42);
|
||||
sendPort.send('done');
|
||||
}
|
Loading…
Reference in a new issue