Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(975)

Side by Side Diff: lib/isolate/frog/isolateimpl.dart

Issue 9662024: Refactor, rename, and generally rationalize code in the Frog isolates library, (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « lib/isolate/frog/compiler_hooks.dart ('k') | lib/isolate/frog/messages.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 /** 5 /**
6 * Concepts used here:
7 *
8 * "manager" - A manager contains one or more isolates, schedules their
9 * execution, and performs other plumbing on their behalf. The isolate
10 * present at the creation of the manager is designated as its "root isolate".
11 * A manager may, for example, be implemented on a web Worker.
12 *
13 * [_Manager] - State present within a manager (exactly once, as a global).
14 *
15 * [_ManagerStub] - A handle held within one manager that allows interaction
16 * with another manager. A target manager may be addressed by zero or more
17 * [_ManagerStub]s.
18 *
19 */
20
21 /**
6 * A native object that is shared across isolates. This object is visible to all 22 * A native object that is shared across isolates. This object is visible to all
7 * isolates running on the same worker (either UI or background web worker). 23 * isolates running under the same manager (either UI or background web worker).
8 * 24 *
9 * This is code that is intended to 'escape' the isolate boundaries in order to 25 * This is code that is intended to 'escape' the isolate boundaries in order to
10 * implement the semantics of isolates in JavaScript. Without this we would have 26 * implement the semantics of isolates in JavaScript. Without this we would have
11 * been forced to implement more code (including the top-level event loop) in 27 * been forced to implement more code (including the top-level event loop) in
12 * JavaScript itself. 28 * JavaScript itself.
13 */ 29 */
14 _GlobalState get _globalState() native "return \$globalState;"; 30 // TODO(eub, sigmund): move the "manager" to be entirely in JS.
15 set _globalState(_GlobalState val) native "\$globalState = val;"; 31 // Running any Dart code outside the context of an isolate gives it
32 // the change to break the isolate abstraction.
33 _Manager get _globalState() native "return \$globalState;";
34 set _globalState(_Manager val) native "\$globalState = val;";
16 35
17 void _fillStatics(context) native @""" 36 void _fillStatics(context) native @"""
18 $globals = context.isolateStatics; 37 $globals = context.isolateStatics;
19 $static_init(); 38 $static_init();
20 """; 39 """;
21 40
22 ReceivePort _port; 41 ReceivePort _port;
23 42
24 SendPort _spawnFunction(void topLevelFunction()) { 43 SendPort _spawnFunction(void topLevelFunction()) {
25 final name = _IsolateNatives._getJSFunctionName(topLevelFunction); 44 final name = _IsolateNatives._getJSFunctionName(topLevelFunction);
26 if (name == null) { 45 if (name == null) {
27 throw new UnsupportedOperationException( 46 throw new UnsupportedOperationException(
28 "only top-level functions can be spawned."); 47 "only top-level functions can be spawned.");
29 } 48 }
30 return _IsolateNatives._spawn2(name, null, false); 49 return _IsolateNatives._spawn2(name, null, false);
31 } 50 }
32 51
33 SendPort _spawnUri(String uri) { 52 SendPort _spawnUri(String uri) {
34 return _IsolateNatives._spawn2(null, uri, false); 53 return _IsolateNatives._spawn2(null, uri, false);
35 } 54 }
36 55
37 /** Global state associated with the current worker. See [globalState]. */ 56 /** State associated with the current manager. See [globalState]. */
38 // TODO(sigmund): split in multiple classes: global, thread, main-worker states? 57 // TODO(sigmund): split in multiple classes: global, thread, main-worker states?
39 class _GlobalState { 58 class _Manager {
40 59
41 /** Next available isolate id. */ 60 /** Next available isolate id within this [_Manager]. */
42 int nextIsolateId = 0; 61 int nextIsolateId = 0;
43 62
44 /** Worker id associated with this worker. */ 63 /** id assigned to this [_Manager]. */
45 int currentWorkerId = 0; 64 int currentManagerId = 0;
46 65
47 /** 66 /**
48 * Next available worker id. Only used by the main worker to assign a unique 67 * Next available manager id. Only used by the main manager to assign a unique
49 * id to each worker created by it. 68 * id to each manager created by it.
50 */ 69 */
51 int nextWorkerId = 1; 70 int nextManagerId = 1;
52 71
53 /** Context for the currently running [Isolate]. */ 72 /** Context for the currently running [Isolate]. */
54 _IsolateContext currentContext = null; 73 _IsolateContext currentContext = null;
55 74
56 /** Context for the root [Isolate] that first run in this worker. */ 75 /** Context for the root [Isolate] that first run in this [_Manager]. */
57 _IsolateContext rootContext = null; 76 _IsolateContext rootContext = null;
58 77
59 /** The top-level event loop. */ 78 /** The top-level event loop. */
60 _EventLoop topEventLoop; 79 _EventLoop topEventLoop;
61 80
62 /** Whether this program is running in a background worker. */ 81 /** Whether this program is running from the command line. */
82 bool fromCommandLine;
83
84 /** Whether this [_Manager] is running as a web worker. */
63 bool isWorker; 85 bool isWorker;
64 86
65 /** Whether this program is running in a UI worker. */ 87 /** Whether we support spawning web workers. */
66 bool inWindow;
67
68 /** Whether we support spawning workers. */
69 bool supportsWorkers; 88 bool supportsWorkers;
70 89
71 /** 90 /**
72 * Whether to use web workers when implementing isolates. Set to false for 91 * Whether to use web workers when implementing isolates. Set to false for
73 * debugging/testing. 92 * debugging/testing.
74 */ 93 */
75 bool get useWorkers() => supportsWorkers; 94 bool get useWorkers() => supportsWorkers;
76 95
77 /** 96 /**
78 * Whether to use the web-worker JSON-based message serialization protocol. By 97 * Whether to use the web-worker JSON-based message serialization protocol. By
79 * default this is only used with web workers. For debugging, you can force 98 * default this is only used with web workers. For debugging, you can force
80 * using this protocol by changing this field value to [true]. 99 * using this protocol by changing this field value to [true].
81 */ 100 */
82 bool get needSerialization() => useWorkers; 101 bool get needSerialization() => useWorkers;
83 102
84 /** 103 /**
85 * Registry of isolates. Isolates must be registered if, and only if, receive 104 * Registry of isolates. Isolates must be registered if, and only if, receive
86 * ports are alive. Normally no open receive-ports means that the isolate is 105 * ports are alive. Normally no open receive-ports means that the isolate is
87 * dead, but DOM callbacks could resurrect it. 106 * dead, but DOM callbacks could resurrect it.
88 */ 107 */
89 Map<int, _IsolateContext> isolates; 108 Map<int, _IsolateContext> isolates;
90 109
91 /** Reference to the main worker. */ 110 /** Reference to the main [_Manager]. Null in the main [_Manager] itself. */
92 _MainWorker mainWorker; 111 _ManagerStub mainManager;
93 112
94 /** Registry of active workers. Only used in the main worker. */ 113 /** Registry of active [_ManagerStub]s. Only used in the main [_Manager]. */
95 Map<int, Dynamic> workers; 114 Map<int, _ManagerStub> managers;
96 115
97 _GlobalState() { 116 _Manager() {
117 _nativeDetectEnvironment();
98 topEventLoop = new _EventLoop(); 118 topEventLoop = new _EventLoop();
99 isolates = {}; 119 isolates = {};
100 workers = {}; 120 managers = {};
101 mainWorker = new _MainWorker(); 121 if (isWorker) { // "if we are not the main manager ourself" is the intent.
102 _nativeInit(); 122 mainManager = new _MainManagerStub();
123 _nativeInitWorkerMessageHandler();
124 }
103 } 125 }
104 126
105 void _nativeInit() native @""" 127 void _nativeDetectEnvironment() native @"""
106 this.isWorker = typeof ($globalThis['importScripts']) != 'undefined'; 128 this.isWorker = typeof ($globalThis['importScripts']) != 'undefined';
107 this.inWindow = typeof(window) !== 'undefined'; 129 this.fromCommandLine = typeof(window) == 'undefined';
108 this.supportsWorkers = this.isWorker || 130 this.supportsWorkers = this.isWorker ||
109 ((typeof $globalThis['Worker']) != 'undefined'); 131 ((typeof $globalThis['Worker']) != 'undefined');
110 if (this.isWorker) { 132 """;
111 $globalThis.onmessage = function (e) { 133
112 _IsolateNatives._processWorkerMessage(this.mainWorker, e); 134 void _nativeInitWorkerMessageHandler() native @"""
113 }; 135 $globalThis.onmessage = function (e) {
136 _IsolateNatives._processWorkerMessage(this.mainManager, e);
114 } 137 }
115 """ { 138 """ {
116 // Declare that the native code has a dependency on this fn.
117 _IsolateNatives._processWorkerMessage(null, null); 139 _IsolateNatives._processWorkerMessage(null, null);
118 } 140 }
119 141
120 /** 142 /// Close the worker running this code if all isolates are done.
121 * Close the worker running this code, called when there is nothing else to 143 void maybeCloseWorker() {
122 * run. 144 if (isolates.isEmpty()) {
123 */ 145 mainManager.postMessage(_serializeMessage({'command': 'close'}));
124 void closeWorker() {
125 if (isWorker) {
126 if (!isolates.isEmpty()) return;
127 mainWorker.postMessage(
128 _serializeMessage({'command': 'close'}));
129 } else if (isolates.containsKey(rootContext.id) && workers.isEmpty() &&
130 !supportsWorkers && !inWindow) {
131 // This should only trigger when running on the command-line.
132 // We don't want this check to execute in the browser where the isolate
133 // might still be alive due to DOM callbacks.
134 throw new Exception("Program exited with open ReceivePorts.");
135 } 146 }
136 } 147 }
137 } 148 }
138 149
139 /** Context information tracked for each isolate. */ 150 /** Context information tracked for each isolate. */
140 class _IsolateContext { 151 class _IsolateContext {
141 /** Current isolate id. */ 152 /** Current isolate id. */
142 int id; 153 int id;
143 154
144 /** Registry of receive ports currently active on this isolate. */ 155 /** Registry of receive ports currently active on this isolate. */
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
220 231
221 _IsolateEvent dequeue() { 232 _IsolateEvent dequeue() {
222 if (events.isEmpty()) return null; 233 if (events.isEmpty()) return null;
223 return events.removeFirst(); 234 return events.removeFirst();
224 } 235 }
225 236
226 /** Process a single event, if any. */ 237 /** Process a single event, if any. */
227 bool runIteration() { 238 bool runIteration() {
228 final event = dequeue(); 239 final event = dequeue();
229 if (event == null) { 240 if (event == null) {
230 _globalState.closeWorker(); 241 if (_globalState.isWorker) {
242 _globalState.maybeCloseWorker();
243 } else if (_globalState.rootContext != null &&
244 _globalState.isolates.containsKey(
245 _globalState.rootContext.id) &&
246 _globalState.fromCommandLine &&
247 _globalState.rootContext.ports.isEmpty()) {
248 // We want to reach here only on the main [_Manager] and only
249 // on the command-line. In the browser the isolate might
250 // still be alive due to DOM callbacks, but the presumption is
251 // that on the command-line, no future events can be injected
252 // into the event queue once it's empty. Node has setTimeout
253 // so this presumption is incorrect there. We think(?) that
254 // in d8 this assumption is valid.
255 throw new Exception("Program exited with open ReceivePorts.");
256 }
231 return false; 257 return false;
232 } 258 }
233 event.process(); 259 event.process();
234 return true; 260 return true;
235 } 261 }
236 262
237 /** 263 /**
238 * Runs multiple iterations of the run-loop. If possible, each iteration is 264 * Runs multiple iterations of the run-loop. If possible, each iteration is
239 * run asynchronously. 265 * run asynchronously.
240 */ 266 */
(...skipping 15 matching lines...) Expand all
256 * Call [_runHelper] but ensure that worker exceptions are propragated. Note 282 * Call [_runHelper] but ensure that worker exceptions are propragated. Note
257 * this is called from JavaScript (see $wrap_call in corejs.dart). 283 * this is called from JavaScript (see $wrap_call in corejs.dart).
258 */ 284 */
259 void run() { 285 void run() {
260 if (!_globalState.isWorker) { 286 if (!_globalState.isWorker) {
261 _runHelper(); 287 _runHelper();
262 } else { 288 } else {
263 try { 289 try {
264 _runHelper(); 290 _runHelper();
265 } catch(var e, var trace) { 291 } catch(var e, var trace) {
266 _globalState.mainWorker.postMessage(_serializeMessage( 292 _globalState.mainManager.postMessage(_serializeMessage(
267 {'command': 'error', 'msg': '$e\n$trace' })); 293 {'command': 'error', 'msg': '$e\n$trace' }));
268 } 294 }
269 } 295 }
270 } 296 }
271 } 297 }
272 298
273 /** An event in the top-level event queue. */ 299 /** An event in the top-level event queue. */
274 class _IsolateEvent { 300 class _IsolateEvent {
275 _IsolateContext isolate; 301 _IsolateContext isolate;
276 Function fn; 302 Function fn;
277 String message; 303 String message;
278 304
279 _IsolateEvent(this.isolate, this.fn, this.message); 305 _IsolateEvent(this.isolate, this.fn, this.message);
280 306
281 void process() { 307 void process() {
282 isolate.eval(fn); 308 isolate.eval(fn);
283 } 309 }
284 } 310 }
285 311
312 /** An interface for a stub used to interact with a manager. */
313 interface _ManagerStub {
314 get id();
315 void set id(int i);
316 void set onmessage(Function f);
317 void postMessage(msg);
318 void terminate();
319 }
286 320
287 /** Default worker. */ 321 /** A stub for interacting with the main manager. */
288 class _MainWorker { 322 class _MainManagerStub implements _ManagerStub {
289 int id = 0; 323 get id() => 0;
324 void set id(int i) { throw new NotImplementedException(); }
290 void postMessage(msg) native @"$globalThis.postMessage(msg);"; 325 void postMessage(msg) native @"$globalThis.postMessage(msg);";
291 void terminate() {} 326 void terminate() {} // Nothing useful to do here.
292 } 327 }
293 328
294 /** 329 /**
295 * A web worker. This type is also defined in 'dart:dom', but we define it here 330 * A stub for interacting with a manager built on a web worker. The type
296 * to avoid introducing a dependency from corelib to dom. This definition uses a 331 * Worker is also defined in 'dart:dom', but we define it here to avoid
332 * introducing a dependency from corelib to dom. This definition uses a
297 * 'hidden' type (* prefix on the native name) to enforce that the type is 333 * 'hidden' type (* prefix on the native name) to enforce that the type is
298 * defined dynamically only when web workers are actually available. 334 * defined dynamically only when web workers are actually available.
299 */ 335 */
300 class _Worker native "*Worker" { 336 class _WorkerStub implements _ManagerStub native "*Worker" {
301 get id() native "return this.id;"; 337 get id() native "return this.id;";
302 void set id(i) native "this.id = i;"; 338 void set id(i) native "this.id = i;";
303 void set onmessage(f) native "this.onmessage = f;"; 339 void set onmessage(f) native "this.onmessage = f;";
304 void postMessage(msg) native "return this.postMessage(msg);"; 340 void postMessage(msg) native "return this.postMessage(msg);";
341 // terminate() is implemented by Worker.
305 } 342 }
306 343
307 final String _SPAWNED_SIGNAL = "spawned"; 344 final String _SPAWNED_SIGNAL = "spawned";
308 345
309 class _IsolateNatives { 346 class _IsolateNatives {
310 347
311 /** JavaScript-specific implementation to spawn an isolate. */ 348 /** JavaScript-specific implementation to spawn an isolate. */
312 static Future<SendPort> spawn(Isolate isolate, bool isLight) { 349 static Future<SendPort> spawn(Isolate isolate, bool isLight) {
313 Completer<SendPort> completer = new Completer<SendPort>(); 350 Completer<SendPort> completer = new Completer<SendPort>();
314 ReceivePort port = new ReceivePort(); 351 ReceivePort port = new ReceivePort();
(...skipping 10 matching lines...) Expand all
325 } else { 362 } else {
326 _startNonWorker(isolate, port.toSendPort()); 363 _startNonWorker(isolate, port.toSendPort());
327 } 364 }
328 365
329 return completer.future; 366 return completer.future;
330 } 367 }
331 368
332 static SendPort _startWorker(Isolate runnable, SendPort replyPort) { 369 static SendPort _startWorker(Isolate runnable, SendPort replyPort) {
333 var factoryName = _getJSConstructorName(runnable); 370 var factoryName = _getJSConstructorName(runnable);
334 if (_globalState.isWorker) { 371 if (_globalState.isWorker) {
335 _globalState.mainWorker.postMessage(_serializeMessage({ 372 _globalState.mainManager.postMessage(_serializeMessage({
336 'command': 'spawn-worker', 373 'command': 'spawn-worker',
337 'factoryName': factoryName, 374 'factoryName': factoryName,
338 'replyPort': _serializeMessage(replyPort)})); 375 'replyPort': _serializeMessage(replyPort)}));
339 } else { 376 } else {
340 _spawnWorker(factoryName, _serializeMessage(replyPort)); 377 _spawnWorker(factoryName, _serializeMessage(replyPort));
341 } 378 }
342 } 379 }
343 380
344 /** 381 /**
345 * The src url for the script tag that loaded this code. Used to create 382 * The src url for the script tag that loaded this code. Used to create
(...skipping 22 matching lines...) Expand all
368 var src = script && script.src; 405 var src = script && script.src;
369 if (!src) { 406 if (!src) {
370 // TODO() 407 // TODO()
371 src = "FIXME:5407062" + "_" + Math.random().toString(); 408 src = "FIXME:5407062" + "_" + Math.random().toString();
372 if (script) script.src = src; 409 if (script) script.src = src;
373 } 410 }
374 return src; 411 return src;
375 """; 412 """;
376 413
377 /** Starts a new worker with the given URL. */ 414 /** Starts a new worker with the given URL. */
378 static _Worker _newWorker(url) native "return new Worker(url);"; 415 static _WorkerStub _newWorker(url) native "return new Worker(url);";
379 416
380 /** 417 /**
381 * Spawns an isolate in a worker. [factoryName] is the Javascript constructor 418 * Spawns an isolate in a worker. [factoryName] is the Javascript constructor
382 * name for the isolate entry point class. 419 * name for the isolate entry point class.
383 */ 420 */
384 static void _spawnWorker(factoryName, serializedReplyPort) { 421 static void _spawnWorker(factoryName, serializedReplyPort) {
385 final worker = _newWorker(_thisScript); 422 final worker = _newWorker(_thisScript);
386 worker.onmessage = (e) { _processWorkerMessage(worker, e); }; 423 worker.onmessage = (e) { _processWorkerMessage(worker, e); };
387 var workerId = _globalState.nextWorkerId++; 424 var workerId = _globalState.nextManagerId++;
388 // We also store the id on the worker itself so that we can unregister it. 425 // We also store the id on the worker itself so that we can unregister it.
389 worker.id = workerId; 426 worker.id = workerId;
390 _globalState.workers[workerId] = worker; 427 _globalState.managers[workerId] = worker;
391 worker.postMessage(_serializeMessage({ 428 worker.postMessage(_serializeMessage({
392 'command': 'start', 429 'command': 'start',
393 'id': workerId, 430 'id': workerId,
394 'replyTo': serializedReplyPort, 431 'replyTo': serializedReplyPort,
395 'factoryName': factoryName })); 432 'factoryName': factoryName }));
396 } 433 }
397 434
398 /** 435 /**
399 * Assume that [e] is a browser message event and extract its message data. 436 * Assume that [e] is a browser message event and extract its message data.
400 * We don't import the dom explicitly so, when workers are disabled, this 437 * We don't import the dom explicitly so, when workers are disabled, this
401 * library can also run on top of nodejs. 438 * library can also run on top of nodejs.
402 */ 439 */
403 static _getEventData(e) native "return e.data"; 440 static _getEventData(e) native "return e.data";
404 441
405 /** 442 /**
406 * Process messages on a worker, either to control the worker instance or to 443 * Process messages on a worker, either to control the worker instance or to
407 * pass messages along to the isolate running in the worker. 444 * pass messages along to the isolate running in the worker.
408 */ 445 */
409 static void _processWorkerMessage(sender, e) { 446 static void _processWorkerMessage(sender, e) {
410 var msg = _deserializeMessage(_getEventData(e)); 447 var msg = _deserializeMessage(_getEventData(e));
411 switch (msg['command']) { 448 switch (msg['command']) {
412 // TODO(sigmund): delete after we migrate to the new API 449 // TODO(sigmund): delete after we migrate to the new API
413 case 'start': 450 case 'start':
414 _globalState.currentWorkerId = msg['id']; 451 _globalState.currentManagerId = msg['id'];
415 var runnerObject = 452 var runnerObject =
416 _allocate(_getJSConstructorFromName(msg['factoryName'])); 453 _allocate(_getJSConstructorFromName(msg['factoryName']));
417 var serializedReplyTo = msg['replyTo']; 454 var serializedReplyTo = msg['replyTo'];
418 _globalState.topEventLoop.enqueue(new _IsolateContext(), function() { 455 _globalState.topEventLoop.enqueue(new _IsolateContext(), function() {
419 var replyTo = _deserializeMessage(serializedReplyTo); 456 var replyTo = _deserializeMessage(serializedReplyTo);
420 _startIsolate(runnerObject, replyTo); 457 _startIsolate(runnerObject, replyTo);
421 }, 'worker-start'); 458 }, 'worker-start');
422 _globalState.topEventLoop.run(); 459 _globalState.topEventLoop.run();
423 break; 460 break;
424 case 'start2': 461 case 'start2':
425 _globalState.currentWorkerId = msg['id']; 462 _globalState.currentManagerId = msg['id'];
426 Function entryPoint = _getJSFunctionFromName(msg['functionName']); 463 Function entryPoint = _getJSFunctionFromName(msg['functionName']);
427 var replyTo = _deserializeMessage(msg['replyTo']); 464 var replyTo = _deserializeMessage(msg['replyTo']);
428 _globalState.topEventLoop.enqueue(new _IsolateContext(), function() { 465 _globalState.topEventLoop.enqueue(new _IsolateContext(), function() {
429 _startIsolate2(entryPoint, replyTo); 466 _startIsolate2(entryPoint, replyTo);
430 }, 'worker-start'); 467 }, 'worker-start');
431 _globalState.topEventLoop.run(); 468 _globalState.topEventLoop.run();
432 break; 469 break;
433 // TODO(sigmund): delete after we migrate to the new API 470 // TODO(sigmund): delete after we migrate to the new API
434 case 'spawn-worker': 471 case 'spawn-worker':
435 _spawnWorker(msg['factoryName'], msg['replyPort']); 472 _spawnWorker(msg['factoryName'], msg['replyPort']);
436 break; 473 break;
437 case 'spawn-worker2': 474 case 'spawn-worker2':
438 _spawnWorker2(msg['functionName'], msg['uri'], msg['replyPort']); 475 _spawnWorker2(msg['functionName'], msg['uri'], msg['replyPort']);
439 break; 476 break;
440 case 'message': 477 case 'message':
441 msg['port'].send(msg['msg'], msg['replyTo']); 478 msg['port'].send(msg['msg'], msg['replyTo']);
442 _globalState.topEventLoop.run(); 479 _globalState.topEventLoop.run();
443 break; 480 break;
444 case 'close': 481 case 'close':
445 _log("Closing Worker"); 482 _log("Closing Worker");
446 _globalState.workers.remove(sender.id); 483 _globalState.managers.remove(sender.id);
447 sender.terminate(); 484 sender.terminate();
448 _globalState.topEventLoop.run(); 485 _globalState.topEventLoop.run();
449 break; 486 break;
450 case 'log': 487 case 'log':
451 _log(msg['msg']); 488 _log(msg['msg']);
452 break; 489 break;
453 case 'print': 490 case 'print':
454 if (_globalState.isWorker) { 491 if (_globalState.isWorker) {
455 _globalState.mainWorker.postMessage( 492 _globalState.mainManager.postMessage(
456 _serializeMessage({'command': 'print', 'msg': msg})); 493 _serializeMessage({'command': 'print', 'msg': msg}));
457 } else { 494 } else {
458 print(msg['msg']); 495 print(msg['msg']);
459 } 496 }
460 break; 497 break;
461 case 'error': 498 case 'error':
462 throw msg['msg']; 499 throw msg['msg'];
463 } 500 }
464 } 501 }
465 502
466 /** Log a message, forwarding to the main worker if appropriate. */ 503 /** Log a message, forwarding to the main [_Manager] if appropriate. */
467 static _log(msg) { 504 static _log(msg) {
468 if (_globalState.isWorker) { 505 if (_globalState.isWorker) {
469 _globalState.mainWorker.postMessage( 506 _globalState.mainManager.postMessage(
470 _serializeMessage({'command': 'log', 'msg': msg })); 507 _serializeMessage({'command': 'log', 'msg': msg }));
471 } else { 508 } else {
472 try { 509 try {
473 _consoleLog(msg); 510 _consoleLog(msg);
474 } catch(e, trace) { 511 } catch(e, trace) {
475 throw new Exception(trace); 512 throw new Exception(trace);
476 } 513 }
477 } 514 }
478 } 515 }
479 516
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
576 } else { 613 } else {
577 _startNonWorker2(functionName, uri, signalReply); 614 _startNonWorker2(functionName, uri, signalReply);
578 } 615 }
579 return new _BufferingSendPort( 616 return new _BufferingSendPort(
580 _globalState.currentContext.id, completer.future); 617 _globalState.currentContext.id, completer.future);
581 } 618 }
582 619
583 static SendPort _startWorker2( 620 static SendPort _startWorker2(
584 String functionName, String uri, SendPort replyPort) { 621 String functionName, String uri, SendPort replyPort) {
585 if (_globalState.isWorker) { 622 if (_globalState.isWorker) {
586 _globalState.mainWorker.postMessage(_serializeMessage({ 623 _globalState.mainManager.postMessage(_serializeMessage({
587 'command': 'spawn-worker2', 624 'command': 'spawn-worker2',
588 'functionName': functionName, 625 'functionName': functionName,
589 'uri': uri, 626 'uri': uri,
590 'replyPort': replyPort})); 627 'replyPort': replyPort}));
591 } else { 628 } else {
592 _spawnWorker2(functionName, uri, replyPort); 629 _spawnWorker2(functionName, uri, replyPort);
593 } 630 }
594 } 631 }
595 632
596 static SendPort _startNonWorker2( 633 static SendPort _startNonWorker2(
(...skipping 22 matching lines...) Expand all
619 if (functionName == null) functionName = 'main'; 656 if (functionName == null) functionName = 'main';
620 if (uri == null) uri = _thisScript; 657 if (uri == null) uri = _thisScript;
621 if (!(new Uri.fromString(uri).isAbsolute())) { 658 if (!(new Uri.fromString(uri).isAbsolute())) {
622 // The constructor of dom workers requires an absolute URL. If we use a 659 // The constructor of dom workers requires an absolute URL. If we use a
623 // relative path we will get a DOM exception. 660 // relative path we will get a DOM exception.
624 String prefix = _thisScript.substring(0, _thisScript.lastIndexOf('/')); 661 String prefix = _thisScript.substring(0, _thisScript.lastIndexOf('/'));
625 uri = "$prefix/$uri"; 662 uri = "$prefix/$uri";
626 } 663 }
627 final worker = _newWorker(uri); 664 final worker = _newWorker(uri);
628 worker.onmessage = (e) { _processWorkerMessage(worker, e); }; 665 worker.onmessage = (e) { _processWorkerMessage(worker, e); };
629 var workerId = _globalState.nextWorkerId++; 666 var workerId = _globalState.nextManagerId++;
630 // We also store the id on the worker itself so that we can unregister it. 667 // We also store the id on the worker itself so that we can unregister it.
631 worker.id = workerId; 668 worker.id = workerId;
632 _globalState.workers[workerId] = worker; 669 _globalState.managers[workerId] = worker;
633 worker.postMessage(_serializeMessage({ 670 worker.postMessage(_serializeMessage({
634 'command': 'start2', 671 'command': 'start2',
635 'id': workerId, 672 'id': workerId,
636 // Note: we serialize replyPort twice because the child worker needs to 673 // Note: we serialize replyPort twice because the child worker needs to
637 // first deserialize the worker id, before it can correctly deserialize 674 // first deserialize the worker id, before it can correctly deserialize
638 // the port (port deserialization is sensitive to what is the current 675 // the port (port deserialization is sensitive to what is the current
639 // workerId). 676 // workerId).
640 'replyTo': _serializeMessage(replyPort), 677 'replyTo': _serializeMessage(replyPort),
641 'functionName': functionName })); 678 'functionName': functionName }));
642 } 679 }
643 } 680 }
OLDNEW
« no previous file with comments | « lib/isolate/frog/compiler_hooks.dart ('k') | lib/isolate/frog/messages.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698