| Index: sdk/lib/_internal/lib/isolate_helper.dart
|
| diff --git a/sdk/lib/_internal/lib/isolate_helper.dart b/sdk/lib/_internal/lib/isolate_helper.dart
|
| index 691cfe20ccf03d34063c5f351ae489a0cd24d4b1..ffea5116229dafa8bb0401059578037b3d42f00d 100644
|
| --- a/sdk/lib/_internal/lib/isolate_helper.dart
|
| +++ b/sdk/lib/_internal/lib/isolate_helper.dart
|
| @@ -32,7 +32,6 @@ _callInIsolate(_IsolateContext isolate, Function function) {
|
| return result;
|
| }
|
|
|
| -/// Marks entering a javascript async operation to keep the worker alive.
|
| /// Marks entering a JavaScript async operation to keep the worker alive.
|
| ///
|
| /// To be called by library code before starting an async operation controlled
|
| @@ -277,6 +276,9 @@ class _IsolateContext implements IsolateContext {
|
| List<_IsolateEvent> delayedEvents = [];
|
| Set<Capability> pauseTokens = new Set();
|
|
|
| + // Container with the "on exit" handler send-ports.
|
| + var doneHandlers;
|
| +
|
| _IsolateContext() {
|
| this.registerWeak(controlPort._id, controlPort);
|
| }
|
| @@ -302,6 +304,21 @@ class _IsolateContext implements IsolateContext {
|
| _updateGlobalState();
|
| }
|
|
|
| + void addDoneListener(SendPort responsePort) {
|
| + if (doneHandlers == null) {
|
| + doneHandlers = [];
|
| + }
|
| + // If necessary, we can switch doneHandlers to a Set if it gets larger.
|
| + // That is not expected to happen in practice.
|
| + if (doneHandlers.contains(responsePort)) return;
|
| + doneHandlers.add(responsePort);
|
| + }
|
| +
|
| + void removeDoneListener(SendPort responsePort) {
|
| + if (doneHandlers == null) return;
|
| + doneHandlers.remove(responsePort);
|
| + }
|
| +
|
| /**
|
| * Run [code] in the context of the isolate represented by [this].
|
| */
|
| @@ -331,8 +348,14 @@ class _IsolateContext implements IsolateContext {
|
| case "resume":
|
| removePause(message[1]);
|
| break;
|
| + case 'add-ondone':
|
| + addDoneListener(message[1]);
|
| + break;
|
| + case 'remove-ondone':
|
| + removeDoneListener(message[1]);
|
| + break;
|
| default:
|
| - print("UNKOWN MESSAGE: $message");
|
| + print("UNKNOWN MESSAGE: $message");
|
| }
|
| }
|
|
|
| @@ -362,11 +385,22 @@ class _IsolateContext implements IsolateContext {
|
| _addRegistration(portId, port);
|
| }
|
|
|
| - _updateGlobalState() {
|
| + void _updateGlobalState() {
|
| if (ports.length - weakPorts.length > 0 || isPaused) {
|
| _globalState.isolates[id] = this; // indicate this isolate is active
|
| } else {
|
| - _globalState.isolates.remove(id); // indicate this isolate is not active
|
| + _shutdown();
|
| + }
|
| + }
|
| +
|
| + void _shutdown() {
|
| + _globalState.isolates.remove(id); // indicate this isolate is not active
|
| + // Send "done" event to all listeners. This must be done after deactivating
|
| + // the current isolate, or it may get events if listening to itself.
|
| + if (doneHandlers != null) {
|
| + for (SendPort port in doneHandlers) {
|
| + port.send(null);
|
| + }
|
| }
|
| }
|
|
|
| @@ -520,7 +554,7 @@ class IsolateNatives {
|
| static final Expando<int> workerIds = new Expando<int>();
|
|
|
| /**
|
| - * The src url for the script tag that loaded this code. Used to create
|
| + * The src url for the script tag that loaded this Used to create
|
| * JavaScript workers.
|
| */
|
| static String computeThisScript() {
|
|
|