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) { |