Chromium Code Reviews| 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..2cf7c9272cf4cac9f7f71f48935a624ebb9e735a 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 |
| @@ -270,6 +269,7 @@ class _IsolateContext implements IsolateContext { |
| final RawReceivePortImpl controlPort = new RawReceivePortImpl._controlPort(); |
| final Capability pauseCapability = new Capability(); |
| + final Capability inspectCapability = new Capability(); |
| // TODO(lrn): Store these in single "PauseState" object, so they don't take |
| // up as much room when not pausing. |
| @@ -277,6 +277,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 +305,17 @@ class _IsolateContext implements IsolateContext { |
| _updateGlobalState(); |
| } |
| + void addDoneListener(Capability inspect, SendPort response) { |
| + if (inspectCapability != inspect) return; |
| + if (doneHandlers == null) { |
| + doneHandlers = []; |
| + } |
| + // If necessary, we can switch doneHandlers to a Set if it gets larget. |
|
floitsch
2014/02/25 19:25:48
larger.
|
| + // That is not expected to happen in practice. |
| + if (doneHandlers.contains(response)) return; |
| + doneHandlers.add(response); |
| + } |
| + |
| /** |
| * Run [code] in the context of the isolate represented by [this]. |
| */ |
| @@ -331,8 +345,11 @@ class _IsolateContext implements IsolateContext { |
| case "resume": |
| removePause(message[1]); |
| break; |
| + case 'ondone': |
| + addDoneListener(message[1], message[2]); |
| + break; |
| default: |
| - print("UNKOWN MESSAGE: $message"); |
| + print("UNKNOWN MESSAGE: $message"); |
| } |
| } |
| @@ -362,11 +379,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 |
|
floitsch
2014/02/25 19:25:48
"I"ndicate ... 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 +548,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 |
|
floitsch
2014/02/25 19:25:48
missing ".".
|
| * JavaScript workers. |
| */ |
| static String computeThisScript() { |
| @@ -788,7 +816,8 @@ class IsolateNatives { |
| // The isolate's port does not keep the isolate open. |
| replyTo.send([_SPAWNED_SIGNAL, |
| context.controlPort.sendPort, |
| - context.pauseCapability]); |
| + context.pauseCapability, |
| + context.inspectCapability]); |
| void runStartFunction() { |
| if (!isSpawnUri) { |