Make `IsolateRunner.close` not keep the isolate alive if called more than once.
diff --git a/lib/isolate_runner.dart b/lib/isolate_runner.dart
index 15e0f65..19a6233 100644
--- a/lib/isolate_runner.dart
+++ b/lib/isolate_runner.dart
@@ -32,6 +32,11 @@
/// Future returned by [onExit]. Set when [onExit] is first read.
Future<void>? _onExitFuture;
+ /// Future returned by [close].
+ ///
+ /// Avoids hanging if calling [close] twice.
+ Future<void>? _closeFuture;
+
/// Create an [IsolateRunner] wrapper for [isolate]
///
/// The preferred way to create an `IsolateRunner` is to use [spawn]
@@ -78,9 +83,11 @@
/// life cycle.
@override
Future<void> close() {
+ var closeFuture = _closeFuture;
+ if (closeFuture != null) return closeFuture;
var channel = SingleResponseChannel();
_commandPort.send(list2(_shutdown, channel.port));
- return channel.result.then(ignore);
+ return _closeFuture = channel.result.then(ignore);
}
/// Kills the isolate.
diff --git a/test/isolaterunner_test.dart b/test/isolaterunner_test.dart
index a292eb5..52b2796 100644
--- a/test/isolaterunner_test.dart
+++ b/test/isolaterunner_test.dart
@@ -10,15 +10,23 @@
const _ms = Duration(milliseconds: 1);
void main() {
- test('create-close', testCreateClose);
+ group('create-close', testCreateClose);
test('create-run-close', testCreateRunClose);
test('separate-isolates', testSeparateIsolates);
group('isolate functions', testIsolateFunctions);
}
-Future testCreateClose() {
- return IsolateRunner.spawn().then((IsolateRunner runner) {
- return runner.close();
+void testCreateClose() {
+ test('simple', () {
+ return IsolateRunner.spawn().then((IsolateRunner runner) {
+ return runner.close();
+ });
+ });
+ test('close twice', () async {
+ var runner = await IsolateRunner.spawn();
+ await runner.close();
+ // Shouldn't hang!
+ await runner.close();
});
}