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

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() {
98 topEventLoop = new _EventLoop(); 117 topEventLoop = new _EventLoop();
99 isolates = {}; 118 isolates = {};
100 workers = {}; 119 managers = {};
101 mainWorker = new _MainWorker(); 120 mainManager = new _MainManagerStub();
102 _nativeInit(); 121 _nativeInit();
103 } 122 }
104 123
105 void _nativeInit() native @""" 124 void _nativeInit() native @"""
106 this.isWorker = typeof ($globalThis['importScripts']) != 'undefined'; 125 this.isWorker = typeof ($globalThis['importScripts']) != 'undefined';
107 this.inWindow = typeof(window) !== 'undefined'; 126 this.fromCommandLine = typeof(window) == 'undefined';
108 this.supportsWorkers = this.isWorker || 127 this.supportsWorkers = this.isWorker ||
109 ((typeof $globalThis['Worker']) != 'undefined'); 128 ((typeof $globalThis['Worker']) != 'undefined');
110 if (this.isWorker) { 129 if (this.isWorker) {
111 $globalThis.onmessage = function (e) { 130 $globalThis.onmessage = function (e) {
112 _IsolateNatives._processWorkerMessage(this.mainWorker, e); 131 _IsolateNatives._processWorkerMessage(this.mainManager, e);
113 }; 132 };
114 } 133 }
115 """ { 134 """ {
116 // Declare that the native code has a dependency on this fn. 135 // Declare that the native code has a dependency on this fn.
117 _IsolateNatives._processWorkerMessage(null, null); 136 _IsolateNatives._processWorkerMessage(null, null);
118 } 137 }
119 138
120 /** 139 /// Close the worker running this code if all isolates are done.
Siggi Cherem (dart-lang) 2012/03/29 17:21:57 Oh, sorry - I meant to keep it also as /** single
eub 2012/03/29 21:20:44 oops, restored to match.
121 * Close the worker running this code, called when there is nothing else to 140 void maybeCloseWorker() {
122 * run. 141 if (isolates.isEmpty()) {
123 */ 142 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 } 143 }
136 } 144 }
137 } 145 }
138 146
139 /** Context information tracked for each isolate. */ 147 /** Context information tracked for each isolate. */
140 class _IsolateContext { 148 class _IsolateContext {
141 /** Current isolate id. */ 149 /** Current isolate id. */
142 int id; 150 int id;
143 151
144 /** Registry of receive ports currently active on this isolate. */ 152 /** Registry of receive ports currently active on this isolate. */
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
220 228
221 _IsolateEvent dequeue() { 229 _IsolateEvent dequeue() {
222 if (events.isEmpty()) return null; 230 if (events.isEmpty()) return null;
223 return events.removeFirst(); 231 return events.removeFirst();
224 } 232 }
225 233
226 /** Process a single event, if any. */ 234 /** Process a single event, if any. */
227 bool runIteration() { 235 bool runIteration() {
228 final event = dequeue(); 236 final event = dequeue();
229 if (event == null) { 237 if (event == null) {
230 _globalState.closeWorker(); 238 if (_globalState.isWorker) {
239 _globalState.maybeCloseWorker();
240 } else if (_globalState.rootContext != null &&
241 _globalState.isolates.containsKey(
242 _globalState.rootContext.id) &&
243 _globalState.fromCommandLine &&
244 _globalState.rootContext.ports.isEmpty()) {
245 // We want to reach here only on the main [_Manager] and only
246 // on the command-line. In the browser the isolate might
247 // still be alive due to DOM callbacks, but the presumption is
248 // that on the command-line, no future events can be injected
249 // into the event queue once it's empty. Node has setTimeout
250 // so this presumption is incorrect there. We think(?) that
251 // in d8 this assumption is valid.
252 throw new Exception("Program exited with open ReceivePorts.");
253 }
231 return false; 254 return false;
232 } 255 }
233 event.process(); 256 event.process();
234 return true; 257 return true;
235 } 258 }
236 259
237 /** 260 /**
238 * Runs multiple iterations of the run-loop. If possible, each iteration is 261 * Runs multiple iterations of the run-loop. If possible, each iteration is
239 * run asynchronously. 262 * run asynchronously.
240 */ 263 */
(...skipping 15 matching lines...) Expand all
256 * Call [_runHelper] but ensure that worker exceptions are propragated. Note 279 * Call [_runHelper] but ensure that worker exceptions are propragated. Note
257 * this is called from JavaScript (see $wrap_call in corejs.dart). 280 * this is called from JavaScript (see $wrap_call in corejs.dart).
258 */ 281 */
259 void run() { 282 void run() {
260 if (!_globalState.isWorker) { 283 if (!_globalState.isWorker) {
261 _runHelper(); 284 _runHelper();
262 } else { 285 } else {
263 try { 286 try {
264 _runHelper(); 287 _runHelper();
265 } catch(var e, var trace) { 288 } catch(var e, var trace) {
266 _globalState.mainWorker.postMessage(_serializeMessage( 289 _globalState.mainManager.postMessage(_serializeMessage(
267 {'command': 'error', 'msg': '$e\n$trace' })); 290 {'command': 'error', 'msg': '$e\n$trace' }));
268 } 291 }
269 } 292 }
270 } 293 }
271 } 294 }
272 295
273 /** An event in the top-level event queue. */ 296 /** An event in the top-level event queue. */
274 class _IsolateEvent { 297 class _IsolateEvent {
275 _IsolateContext isolate; 298 _IsolateContext isolate;
276 Function fn; 299 Function fn;
277 String message; 300 String message;
278 301
279 _IsolateEvent(this.isolate, this.fn, this.message); 302 _IsolateEvent(this.isolate, this.fn, this.message);
280 303
281 void process() { 304 void process() {
282 isolate.eval(fn); 305 isolate.eval(fn);
283 } 306 }
284 } 307 }
285 308
309 /** An interface for a stub used to interact with a manager. */
310 interface _ManagerStub {
311 get id();
312 void set id(int i);
313 void set onmessage(Function f);
314 void postMessage(msg);
315 void terminate();
316 }
286 317
287 /** Default worker. */ 318 /** A stub for interacting with the main manager. */
288 class _MainWorker { 319 class _MainManagerStub implements _ManagerStub {
289 int id = 0; 320 get id() => 0;
321 void set id(int i) { throw new NotImplementedException(); }
290 void postMessage(msg) native @"$globalThis.postMessage(msg);"; 322 void postMessage(msg) native @"$globalThis.postMessage(msg);";
291 void terminate() {} 323 void terminate() {} // Nothing useful to do here.
292 } 324 }
293 325
294 /** 326 /**
295 * A web worker. This type is also defined in 'dart:dom', but we define it here 327 * 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 328 * Worker is also defined in 'dart:dom', but we define it here to avoid
329 * 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 330 * 'hidden' type (* prefix on the native name) to enforce that the type is
298 * defined dynamically only when web workers are actually available. 331 * defined dynamically only when web workers are actually available.
299 */ 332 */
300 class _Worker native "*Worker" { 333 class _WorkerStub implements _ManagerStub native "*Worker" {
301 get id() native "return this.id;"; 334 get id() native "return this.id;";
302 void set id(i) native "this.id = i;"; 335 void set id(i) native "this.id = i;";
303 void set onmessage(f) native "this.onmessage = f;"; 336 void set onmessage(f) native "this.onmessage = f;";
304 void postMessage(msg) native "return this.postMessage(msg);"; 337 void postMessage(msg) native "return this.postMessage(msg);";
338 // terminate() is implemented by Worker.
305 } 339 }
306 340
307 final String _SPAWNED_SIGNAL = "spawned"; 341 final String _SPAWNED_SIGNAL = "spawned";
308 342
309 class _IsolateNatives { 343 class _IsolateNatives {
310 344
311 /** JavaScript-specific implementation to spawn an isolate. */ 345 /** JavaScript-specific implementation to spawn an isolate. */
312 static Future<SendPort> spawn(Isolate isolate, bool isLight) { 346 static Future<SendPort> spawn(Isolate isolate, bool isLight) {
313 Completer<SendPort> completer = new Completer<SendPort>(); 347 Completer<SendPort> completer = new Completer<SendPort>();
314 ReceivePort port = new ReceivePort(); 348 ReceivePort port = new ReceivePort();
(...skipping 10 matching lines...) Expand all
325 } else { 359 } else {
326 _startNonWorker(isolate, port.toSendPort()); 360 _startNonWorker(isolate, port.toSendPort());
327 } 361 }
328 362
329 return completer.future; 363 return completer.future;
330 } 364 }
331 365
332 static SendPort _startWorker(Isolate runnable, SendPort replyPort) { 366 static SendPort _startWorker(Isolate runnable, SendPort replyPort) {
333 var factoryName = _getJSConstructorName(runnable); 367 var factoryName = _getJSConstructorName(runnable);
334 if (_globalState.isWorker) { 368 if (_globalState.isWorker) {
335 _globalState.mainWorker.postMessage(_serializeMessage({ 369 _globalState.mainManager.postMessage(_serializeMessage({
336 'command': 'spawn-worker', 370 'command': 'spawn-worker',
337 'factoryName': factoryName, 371 'factoryName': factoryName,
338 'replyPort': _serializeMessage(replyPort)})); 372 'replyPort': _serializeMessage(replyPort)}));
339 } else { 373 } else {
340 _spawnWorker(factoryName, _serializeMessage(replyPort)); 374 _spawnWorker(factoryName, _serializeMessage(replyPort));
341 } 375 }
342 } 376 }
343 377
344 /** 378 /**
345 * The src url for the script tag that loaded this code. Used to create 379 * 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; 402 var src = script && script.src;
369 if (!src) { 403 if (!src) {
370 // TODO() 404 // TODO()
371 src = "FIXME:5407062" + "_" + Math.random().toString(); 405 src = "FIXME:5407062" + "_" + Math.random().toString();
372 if (script) script.src = src; 406 if (script) script.src = src;
373 } 407 }
374 return src; 408 return src;
375 """; 409 """;
376 410
377 /** Starts a new worker with the given URL. */ 411 /** Starts a new worker with the given URL. */
378 static _Worker _newWorker(url) native "return new Worker(url);"; 412 static _WorkerStub _newWorker(url) native "return new Worker(url);";
379 413
380 /** 414 /**
381 * Spawns an isolate in a worker. [factoryName] is the Javascript constructor 415 * Spawns an isolate in a worker. [factoryName] is the Javascript constructor
382 * name for the isolate entry point class. 416 * name for the isolate entry point class.
383 */ 417 */
384 static void _spawnWorker(factoryName, serializedReplyPort) { 418 static void _spawnWorker(factoryName, serializedReplyPort) {
385 final worker = _newWorker(_thisScript); 419 final worker = _newWorker(_thisScript);
386 worker.onmessage = (e) { _processWorkerMessage(worker, e); }; 420 worker.onmessage = (e) { _processWorkerMessage(worker, e); };
387 var workerId = _globalState.nextWorkerId++; 421 var workerId = _globalState.nextManagerId++;
388 // We also store the id on the worker itself so that we can unregister it. 422 // We also store the id on the worker itself so that we can unregister it.
389 worker.id = workerId; 423 worker.id = workerId;
390 _globalState.workers[workerId] = worker; 424 _globalState.managers[workerId] = worker;
391 worker.postMessage(_serializeMessage({ 425 worker.postMessage(_serializeMessage({
392 'command': 'start', 426 'command': 'start',
393 'id': workerId, 427 'id': workerId,
394 'replyTo': serializedReplyPort, 428 'replyTo': serializedReplyPort,
395 'factoryName': factoryName })); 429 'factoryName': factoryName }));
396 } 430 }
397 431
398 /** 432 /**
399 * Assume that [e] is a browser message event and extract its message data. 433 * 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 434 * We don't import the dom explicitly so, when workers are disabled, this
401 * library can also run on top of nodejs. 435 * library can also run on top of nodejs.
402 */ 436 */
403 static _getEventData(e) native "return e.data"; 437 static _getEventData(e) native "return e.data";
404 438
405 /** 439 /**
406 * Process messages on a worker, either to control the worker instance or to 440 * Process messages on a worker, either to control the worker instance or to
407 * pass messages along to the isolate running in the worker. 441 * pass messages along to the isolate running in the worker.
408 */ 442 */
409 static void _processWorkerMessage(sender, e) { 443 static void _processWorkerMessage(sender, e) {
410 var msg = _deserializeMessage(_getEventData(e)); 444 var msg = _deserializeMessage(_getEventData(e));
411 switch (msg['command']) { 445 switch (msg['command']) {
412 // TODO(sigmund): delete after we migrate to the new API 446 // TODO(sigmund): delete after we migrate to the new API
413 case 'start': 447 case 'start':
414 _globalState.currentWorkerId = msg['id']; 448 _globalState.currentManagerId = msg['id'];
415 var runnerObject = 449 var runnerObject =
416 _allocate(_getJSConstructorFromName(msg['factoryName'])); 450 _allocate(_getJSConstructorFromName(msg['factoryName']));
417 var serializedReplyTo = msg['replyTo']; 451 var serializedReplyTo = msg['replyTo'];
418 _globalState.topEventLoop.enqueue(new _IsolateContext(), function() { 452 _globalState.topEventLoop.enqueue(new _IsolateContext(), function() {
419 var replyTo = _deserializeMessage(serializedReplyTo); 453 var replyTo = _deserializeMessage(serializedReplyTo);
420 _startIsolate(runnerObject, replyTo); 454 _startIsolate(runnerObject, replyTo);
421 }, 'worker-start'); 455 }, 'worker-start');
422 _globalState.topEventLoop.run(); 456 _globalState.topEventLoop.run();
423 break; 457 break;
424 case 'start2': 458 case 'start2':
425 _globalState.currentWorkerId = msg['id']; 459 _globalState.currentManagerId = msg['id'];
426 Function entryPoint = _getJSFunctionFromName(msg['functionName']); 460 Function entryPoint = _getJSFunctionFromName(msg['functionName']);
427 var replyTo = _deserializeMessage(msg['replyTo']); 461 var replyTo = _deserializeMessage(msg['replyTo']);
428 _globalState.topEventLoop.enqueue(new _IsolateContext(), function() { 462 _globalState.topEventLoop.enqueue(new _IsolateContext(), function() {
429 _startIsolate2(entryPoint, replyTo); 463 _startIsolate2(entryPoint, replyTo);
430 }, 'worker-start'); 464 }, 'worker-start');
431 _globalState.topEventLoop.run(); 465 _globalState.topEventLoop.run();
432 break; 466 break;
433 // TODO(sigmund): delete after we migrate to the new API 467 // TODO(sigmund): delete after we migrate to the new API
434 case 'spawn-worker': 468 case 'spawn-worker':
435 _spawnWorker(msg['factoryName'], msg['replyPort']); 469 _spawnWorker(msg['factoryName'], msg['replyPort']);
436 break; 470 break;
437 case 'spawn-worker2': 471 case 'spawn-worker2':
438 _spawnWorker2(msg['functionName'], msg['uri'], msg['replyPort']); 472 _spawnWorker2(msg['functionName'], msg['uri'], msg['replyPort']);
439 break; 473 break;
440 case 'message': 474 case 'message':
441 msg['port'].send(msg['msg'], msg['replyTo']); 475 msg['port'].send(msg['msg'], msg['replyTo']);
442 _globalState.topEventLoop.run(); 476 _globalState.topEventLoop.run();
443 break; 477 break;
444 case 'close': 478 case 'close':
445 _log("Closing Worker"); 479 _log("Closing Worker");
446 _globalState.workers.remove(sender.id); 480 _globalState.managers.remove(sender.id);
447 sender.terminate(); 481 sender.terminate();
448 _globalState.topEventLoop.run(); 482 _globalState.topEventLoop.run();
449 break; 483 break;
450 case 'log': 484 case 'log':
451 _log(msg['msg']); 485 _log(msg['msg']);
452 break; 486 break;
453 case 'print': 487 case 'print':
454 if (_globalState.isWorker) { 488 if (_globalState.isWorker) {
455 _globalState.mainWorker.postMessage( 489 _globalState.mainManager.postMessage(
456 _serializeMessage({'command': 'print', 'msg': msg})); 490 _serializeMessage({'command': 'print', 'msg': msg}));
457 } else { 491 } else {
458 print(msg['msg']); 492 print(msg['msg']);
459 } 493 }
460 break; 494 break;
461 case 'error': 495 case 'error':
462 throw msg['msg']; 496 throw msg['msg'];
463 } 497 }
464 } 498 }
465 499
466 /** Log a message, forwarding to the main worker if appropriate. */ 500 /** Log a message, forwarding to the main [_Manager] if appropriate. */
467 static _log(msg) { 501 static _log(msg) {
468 if (_globalState.isWorker) { 502 if (_globalState.isWorker) {
469 _globalState.mainWorker.postMessage( 503 _globalState.mainManager.postMessage(
470 _serializeMessage({'command': 'log', 'msg': msg })); 504 _serializeMessage({'command': 'log', 'msg': msg }));
471 } else { 505 } else {
472 try { 506 try {
473 _consoleLog(msg); 507 _consoleLog(msg);
474 } catch(e, trace) { 508 } catch(e, trace) {
475 throw new Exception(trace); 509 throw new Exception(trace);
476 } 510 }
477 } 511 }
478 } 512 }
479 513
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
576 } else { 610 } else {
577 _startNonWorker2(functionName, uri, signalReply); 611 _startNonWorker2(functionName, uri, signalReply);
578 } 612 }
579 return new _BufferingSendPort( 613 return new _BufferingSendPort(
580 _globalState.currentContext.id, completer.future); 614 _globalState.currentContext.id, completer.future);
581 } 615 }
582 616
583 static SendPort _startWorker2( 617 static SendPort _startWorker2(
584 String functionName, String uri, SendPort replyPort) { 618 String functionName, String uri, SendPort replyPort) {
585 if (_globalState.isWorker) { 619 if (_globalState.isWorker) {
586 _globalState.mainWorker.postMessage(_serializeMessage({ 620 _globalState.mainManager.postMessage(_serializeMessage({
587 'command': 'spawn-worker2', 621 'command': 'spawn-worker2',
588 'functionName': functionName, 622 'functionName': functionName,
589 'uri': uri, 623 'uri': uri,
590 'replyPort': replyPort})); 624 'replyPort': replyPort}));
591 } else { 625 } else {
592 _spawnWorker2(functionName, uri, replyPort); 626 _spawnWorker2(functionName, uri, replyPort);
593 } 627 }
594 } 628 }
595 629
596 static SendPort _startNonWorker2( 630 static SendPort _startNonWorker2(
(...skipping 22 matching lines...) Expand all
619 if (functionName == null) functionName = 'main'; 653 if (functionName == null) functionName = 'main';
620 if (uri == null) uri = _thisScript; 654 if (uri == null) uri = _thisScript;
621 if (!(new Uri.fromString(uri).isAbsolute())) { 655 if (!(new Uri.fromString(uri).isAbsolute())) {
622 // The constructor of dom workers requires an absolute URL. If we use a 656 // The constructor of dom workers requires an absolute URL. If we use a
623 // relative path we will get a DOM exception. 657 // relative path we will get a DOM exception.
624 String prefix = _thisScript.substring(0, _thisScript.lastIndexOf('/')); 658 String prefix = _thisScript.substring(0, _thisScript.lastIndexOf('/'));
625 uri = "$prefix/$uri"; 659 uri = "$prefix/$uri";
626 } 660 }
627 final worker = _newWorker(uri); 661 final worker = _newWorker(uri);
628 worker.onmessage = (e) { _processWorkerMessage(worker, e); }; 662 worker.onmessage = (e) { _processWorkerMessage(worker, e); };
629 var workerId = _globalState.nextWorkerId++; 663 var workerId = _globalState.nextManagerId++;
630 // We also store the id on the worker itself so that we can unregister it. 664 // We also store the id on the worker itself so that we can unregister it.
631 worker.id = workerId; 665 worker.id = workerId;
632 _globalState.workers[workerId] = worker; 666 _globalState.managers[workerId] = worker;
633 worker.postMessage(_serializeMessage({ 667 worker.postMessage(_serializeMessage({
634 'command': 'start2', 668 'command': 'start2',
635 'id': workerId, 669 'id': workerId,
636 // Note: we serialize replyPort twice because the child worker needs to 670 // Note: we serialize replyPort twice because the child worker needs to
637 // first deserialize the worker id, before it can correctly deserialize 671 // first deserialize the worker id, before it can correctly deserialize
638 // the port (port deserialization is sensitive to what is the current 672 // the port (port deserialization is sensitive to what is the current
639 // workerId). 673 // workerId).
640 'replyTo': _serializeMessage(replyPort), 674 'replyTo': _serializeMessage(replyPort),
641 'functionName': functionName })); 675 'functionName': functionName }));
642 } 676 }
643 } 677 }
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