| Index: dart/sdk/lib/_internal/compiler/implementation/lib/isolate_helper.dart
|
| diff --git a/dart/sdk/lib/_internal/compiler/implementation/lib/isolate_helper.dart b/dart/sdk/lib/_internal/compiler/implementation/lib/isolate_helper.dart
|
| index ebbb9fd02a566663cd58f7f630b8ba1387d653ff..59ea2eb8640b7f4b638a19162ba5c1c860d86c6f 100644
|
| --- a/dart/sdk/lib/_internal/compiler/implementation/lib/isolate_helper.dart
|
| +++ b/dart/sdk/lib/_internal/compiler/implementation/lib/isolate_helper.dart
|
| @@ -107,7 +107,9 @@ void startRootIsolate(entry) {
|
| * [_ManagerStub] - A handle held within one manager that allows interaction
|
| * with another manager. A target manager may be addressed by zero or more
|
| * [_ManagerStub]s.
|
| - *
|
| + * TODO(ahe): The _ManagerStub concept is broken. It was an attempt
|
| + * to create a common interface between the native Worker class and
|
| + * _MainManagerStub.
|
| */
|
|
|
| /**
|
| @@ -183,10 +185,10 @@ class _Manager {
|
| Map<int, _IsolateContext> isolates;
|
|
|
| /** Reference to the main [_Manager]. Null in the main [_Manager] itself. */
|
| - _ManagerStub mainManager;
|
| + _MainManagerStub mainManager;
|
|
|
| - /** Registry of active [_ManagerStub]s. Only used in the main [_Manager]. */
|
| - Map<int, _ManagerStub> managers;
|
| + /// Registry of active Web Workers. Only used in the main [_Manager].
|
| + Map<int, dynamic /* Worker */> managers;
|
|
|
| /** The entry point given by [startRootIsolate]. */
|
| final Function entry;
|
| @@ -195,7 +197,7 @@ class _Manager {
|
| _nativeDetectEnvironment();
|
| topEventLoop = new _EventLoop();
|
| isolates = new Map<int, _IsolateContext>();
|
| - managers = new Map<int, _ManagerStub>();
|
| + managers = new Map<int, dynamic>();
|
| if (isWorker) { // "if we are not the main manager ourself" is the intent.
|
| mainManager = new _MainManagerStub();
|
| _nativeInitWorkerMessageHandler();
|
| @@ -390,41 +392,17 @@ class _IsolateEvent {
|
| }
|
| }
|
|
|
| -/** An interface for a stub used to interact with a manager. */
|
| -abstract class _ManagerStub {
|
| - get id;
|
| - void set id(int i);
|
| - void set onmessage(Function f);
|
| - void postMessage(msg);
|
| - void terminate();
|
| -}
|
| -
|
| /** A stub for interacting with the main manager. */
|
| -class _MainManagerStub implements _ManagerStub {
|
| - get id => 0;
|
| - void set id(int i) { throw new UnimplementedError(); }
|
| - void set onmessage(f) {
|
| - throw new Exception("onmessage should not be set on MainManagerStub");
|
| - }
|
| +class _MainManagerStub {
|
| void postMessage(msg) {
|
| - JS("void", r"#.postMessage(#)", globalThis, msg);
|
| + // "self" is a way to refer to the global context object that
|
| + // works in HTML pages and in Web Workers. It does not work in d8
|
| + // and Firefox jsshell, because that would have been too easy.
|
| + //
|
| + // See: http://www.w3.org/TR/workers/#the-global-scope
|
| + // and: http://www.w3.org/TR/Window/#dfn-self-attribute
|
| + JS("void", r"self.postMessage(#)", msg);
|
| }
|
| - void terminate() {} // Nothing useful to do here.
|
| -}
|
| -
|
| -/**
|
| - * A stub for interacting with a manager built on a web worker. This
|
| - * definition uses a 'hidden' type (* prefix on the native name) to
|
| - * enforce that the type is defined dynamically only when web workers
|
| - * are actually available.
|
| - */
|
| -// @Native("*Worker");
|
| -class _WorkerStub implements _ManagerStub {
|
| - get id => JS("", "#.id", this);
|
| - void set id(i) { JS("void", "#.id = #", this, i); }
|
| - void set onmessage(f) { JS("void", "#.onmessage = #", this, f); }
|
| - void postMessage(msg) { JS("void", "#.postMessage(#)", this, msg); }
|
| - void terminate() { JS("void", "#.terminate()", this); }
|
| }
|
|
|
| const String _SPAWNED_SIGNAL = "spawned";
|
| @@ -439,6 +417,9 @@ class IsolateNatives {
|
|
|
| static String thisScript = computeThisScript();
|
|
|
| + /// Associates an ID with a native worker object.
|
| + static final Expando<int> workerIds = new Expando<int>();
|
| +
|
| /**
|
| * The src url for the script tag that loaded this code. Used to create
|
| * JavaScript workers.
|
| @@ -488,9 +469,6 @@ class IsolateNatives {
|
|
|
| static computeGlobalThis() => JS('', 'function() { return this; }()');
|
|
|
| - /** Starts a new worker with the given URL. */
|
| - static _WorkerStub _newWorker(url) => JS("_WorkerStub", r"new Worker(#)", url);
|
| -
|
| /**
|
| * Assume that [e] is a browser message event and extract its message data.
|
| * We don't import the dom explicitly so, when workers are disabled, this
|
| @@ -502,7 +480,7 @@ class IsolateNatives {
|
| * Process messages on a worker, either to control the worker instance or to
|
| * pass messages along to the isolate running in the worker.
|
| */
|
| - static void _processWorkerMessage(sender, e) {
|
| + static void _processWorkerMessage(/* Worker */ sender, e) {
|
| var msg = _deserializeMessage(_getEventData(e));
|
| switch (msg['command']) {
|
| case 'start':
|
| @@ -537,9 +515,8 @@ class IsolateNatives {
|
| _globalState.topEventLoop.run();
|
| break;
|
| case 'close':
|
| - _log("Closing Worker");
|
| - _globalState.managers.remove(sender.id);
|
| - sender.terminate();
|
| + _globalState.managers.remove(workerIds[sender]);
|
| + JS('void', '#.terminate()', sender);
|
| _globalState.topEventLoop.run();
|
| break;
|
| case 'log':
|
| @@ -675,24 +652,26 @@ class IsolateNatives {
|
| */
|
| static void _spawnWorker(functionName, uri, replyPort) {
|
| if (uri == null) uri = thisScript;
|
| - final worker = _newWorker(uri);
|
| - worker.onmessage = JS('',
|
| - 'function(e) { #(#, e); }',
|
| - DART_CLOSURE_TO_JS(_processWorkerMessage),
|
| - worker);
|
| + final worker = JS('var', 'new Worker(#)', uri);
|
| +
|
| + var processWorkerMessageTrampoline =
|
| + JS('', 'function(e) { #(#, e); }',
|
| + DART_CLOSURE_TO_JS(_processWorkerMessage),
|
| + worker);
|
| + JS('void', '#.onmessage = #', worker, processWorkerMessageTrampoline);
|
| var workerId = _globalState.nextManagerId++;
|
| // We also store the id on the worker itself so that we can unregister it.
|
| - worker.id = workerId;
|
| + workerIds[worker] = workerId;
|
| _globalState.managers[workerId] = worker;
|
| - worker.postMessage(_serializeMessage({
|
| - 'command': 'start',
|
| - 'id': workerId,
|
| - // Note: we serialize replyPort twice because the child worker needs to
|
| - // first deserialize the worker id, before it can correctly deserialize
|
| - // the port (port deserialization is sensitive to what is the current
|
| - // workerId).
|
| - 'replyTo': _serializeMessage(replyPort),
|
| - 'functionName': functionName }));
|
| + JS('void', '#.postMessage(#)', worker, _serializeMessage({
|
| + 'command': 'start',
|
| + 'id': workerId,
|
| + // Note: we serialize replyPort twice because the child worker needs to
|
| + // first deserialize the worker id, before it can correctly deserialize
|
| + // the port (port deserialization is sensitive to what is the current
|
| + // workerId).
|
| + 'replyTo': _serializeMessage(replyPort),
|
| + 'functionName': functionName }));
|
| }
|
| }
|
|
|
| @@ -807,9 +786,9 @@ class _WorkerSendPort extends _BaseSendPort implements SendPort {
|
| _globalState.mainManager.postMessage(workerMessage);
|
| } else {
|
| // Deliver the message only if the worker is still alive.
|
| - _ManagerStub manager = _globalState.managers[_workerId];
|
| + /* Worker */ var manager = _globalState.managers[_workerId];
|
| if (manager != null) {
|
| - manager.postMessage(workerMessage);
|
| + JS('void', '#.postMessage(#)', manager, workerMessage);
|
| }
|
| }
|
| });
|
|
|