blob: aec9db05e9b9abde6c5c529bad88effe0647f752 [file] [log] [blame]
// Copyright (c) 2018, 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.
//
// Validates functionality of Isolate.exit().
import 'dart:async';
import 'dart:isolate';
import 'dart:nativewrappers';
import "package:expect/expect.dart";
import "isolates/fast_object_copy_test.dart" show nonCopyableClosures;
import "isolates/fast_object_copy2_test.dart"
show sharableObjects, copyableClosures;
doNothingWorker(data) {}
spawnWorker(worker, data) async {
Completer completer = Completer();
runZoned(() async {
final isolate = await Isolate.spawn(worker, [data]);
completer.complete(isolate);
}, onError: (e, st) => completer.complete(e));
return await completer.future;
}
base class NativeWrapperClass extends NativeFieldWrapperClass1 {}
verifyCantSendNative() async {
final receivePort = ReceivePort();
final unsendable = NativeWrapperClass();
Expect.throws(
() => Isolate.exit(receivePort.sendPort, unsendable),
(e) =>
e is ArgumentError &&
e.invalidValue == unsendable &&
e.toString().contains("NativeWrapper"),
);
receivePort.close();
}
verifyCantSendReceivePort() async {
final receivePort = RawReceivePort();
final unsendable = receivePort;
Expect.throws(
() => Isolate.exit(receivePort.sendPort, receivePort),
(e) =>
e is ArgumentError &&
e.invalidValue == unsendable &&
e.toString().contains("ReceivePort"),
);
receivePort.close();
}
verifyCantSendNonCopyable() async {
final port = ReceivePort();
final inbox = StreamIterator<dynamic>(port);
final isolate = await Isolate.spawn((SendPort sendPort) {
for (final closure in nonCopyableClosures) {
Expect.throwsArgumentError(() => Isolate.exit(sendPort, closure));
}
sendPort.send(true);
}, port.sendPort);
await inbox.moveNext();
Expect.isTrue(inbox.current);
port.close();
}
sendShareable(SendPort sendPort) {
Isolate.exit(sendPort, sharableObjects);
}
verifyCanSendShareable() async {
final port = ReceivePort();
final inbox = StreamIterator<dynamic>(port);
final isolate = await Isolate.spawn(sendShareable, port.sendPort);
await inbox.moveNext();
final result = inbox.current;
Expect.equals(sharableObjects.length, result.length);
port.close();
}
sendCopyable(SendPort sendPort) {
Isolate.exit(sendPort, copyableClosures);
}
verifyCanSendCopyableClosures() async {
final port = ReceivePort();
final inbox = StreamIterator<dynamic>(port);
final isolate = await Isolate.spawn(sendCopyable, port.sendPort);
await inbox.moveNext();
final result = inbox.current;
Expect.equals(copyableClosures.length, result.length);
port.close();
}
add(a, b) => a + b;
worker(SendPort sendPort) async {
Isolate.exit(sendPort, add);
}
verifyExitMessageIsPostedLast() async {
final port = ReceivePort();
final inbox = new StreamIterator<dynamic>(port);
final isolate = await Isolate.spawn(
worker,
port.sendPort,
onExit: port.sendPort,
);
final receivedData = Completer<dynamic>();
final isolateExited = Completer<bool>();
port.listen((dynamic resultData) {
if (receivedData.isCompleted) {
Expect.equals(
null,
resultData,
); // exit message comes after data is receivedData
isolateExited.complete(true);
} else {
receivedData.complete(resultData);
}
});
Expect.equals(true, await isolateExited.future);
Expect.equals(5, (await receivedData.future)(2, 3));
port.close();
}
main() async {
await verifyCantSendNative();
await verifyCantSendReceivePort();
await verifyCanSendShareable();
await verifyCanSendCopyableClosures();
await verifyExitMessageIsPostedLast();
}