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

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, 9 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 _Manager get _globalState() native "return \$globalState;";
15 set _globalState(_GlobalState val) native "\$globalState = val;"; 31 set _globalState(_Manager val) native "\$globalState = val;";
16 32
17 void _fillStatics(context) native @""" 33 void _fillStatics(context) native @"""
18 $globals = context.isolateStatics; 34 $globals = context.isolateStatics;
19 $static_init(); 35 $static_init();
20 """; 36 """;
21 37
22 /** Global state associated with the current worker. See [globalState]. */ 38 /** State associated with the current manager. See [globalState]. */
23 // TODO(sigmund): split in multiple classes: global, thread, main-worker states? 39 // TODO(sigmund): split in multiple classes: global, thread, main-worker states?
24 class _GlobalState { 40 class _Manager {
25 41
26 /** Next available isolate id. */ 42 /** Next available isolate id within this [_Manager]. */
27 int nextIsolateId = 0; 43 int nextIsolateId = 0;
28 44
29 /** Worker id associated with this worker. */ 45 /** id assigned to this [_Manager]. */
30 int currentWorkerId = 0; 46 int currentManagerId = 0;
31 47
32 /** 48 /**
33 * Next available worker id. Only used by the main worker to assign a unique 49 * Next available manager id. Only used by the main manager to assign a unique
34 * id to each worker created by it. 50 * id to each manager created by it.
35 */ 51 */
36 int nextWorkerId = 1; 52 int nextManagerId = 1;
37 53
38 /** Context for the currently running [Isolate]. */ 54 /** Context for the currently running [Isolate]. */
39 _IsolateContext currentContext = null; 55 _IsolateContext currentContext = null;
40 56
41 /** Context for the root [Isolate] that first run in this worker. */ 57 /** Context for the root [Isolate] that first run in this [_Manager]. */
42 _IsolateContext rootContext = null; 58 _IsolateContext rootContext = null;
43 59
44 /** The top-level event loop. */ 60 /** The top-level event loop. */
45 _EventLoop topEventLoop; 61 _EventLoop topEventLoop;
46 62
47 /** Whether this program is running in a background worker. */ 63 /** Whether this program is running from the command line. */
64 bool fromCommandLine;
65
66 /** Whether this [_Manager] is running as a web worker. */
48 bool isWorker; 67 bool isWorker;
49 68
50 /** Whether this program is running in a UI worker. */ 69 /** Whether we support spawning web workers. */
51 bool inWindow; 70 // XXX(eub): inside a web worker, is this true (because we can request the
Siggi Cherem (dart-lang) 2012/03/24 00:31:57 the former - true because we can delegate to the m
eub 2012/03/29 00:07:52 (Sorry, this comment should have been gone; I alwa
52 71 // main manager to spawn one) or false (because *we* can't spawn one)?
53 /** Whether we support spawning workers. */
54 bool supportsWorkers; 72 bool supportsWorkers;
55 73
56 /** 74 /**
57 * Whether to use web workers when implementing isolates. Set to false for 75 * Whether to use web workers when implementing isolates. Set to false for
58 * debugging/testing. 76 * debugging/testing.
59 */ 77 */
60 bool get useWorkers() => supportsWorkers; 78 bool get useWorkers() => supportsWorkers;
61 79
62 /** 80 /**
63 * Whether to use the web-worker JSON-based message serialization protocol. By 81 * Whether to use the web-worker JSON-based message serialization protocol. By
64 * default this is only used with web workers. For debugging, you can force 82 * default this is only used with web workers. For debugging, you can force
65 * using this protocol by changing this field value to [true]. 83 * using this protocol by changing this field value to [true].
66 */ 84 */
67 bool get needSerialization() => useWorkers; 85 bool get needSerialization() => useWorkers;
68 86
69 /** 87 /**
70 * Registry of isolates. Isolates must be registered if, and only if, receive 88 * Registry of isolates. Isolates must be registered if, and only if, receive
71 * ports are alive. Normally no open receive-ports means that the isolate is 89 * ports are alive. Normally no open receive-ports means that the isolate is
72 * dead, but DOM callbacks could resurrect it. 90 * dead, but DOM callbacks could resurrect it.
73 */ 91 */
74 Map<int, _IsolateContext> isolates; 92 Map<int, _IsolateContext> isolates;
75 93
76 /** Reference to the main worker. */ 94 /** Reference to the main [_Manager]. Null in the main [_Manager] itself. */
77 _MainWorker mainWorker; 95 _ManagerStub mainManager;
78 96
79 /** Registry of active workers. Only used in the main worker. */ 97 /** Registry of active [_ManagerStub]s. Only used in the main [_Manager]. */
80 Map<int, Dynamic> workers; 98 Map<int, _ManagerStub> managers;
81 99
82 _GlobalState() { 100 _Manager() {
83 topEventLoop = new _EventLoop(); 101 topEventLoop = new _EventLoop();
84 isolates = {}; 102 isolates = {};
85 workers = {}; 103 managers = {};
86 mainWorker = new _MainWorker(); 104 mainManager = new _MainManagerStub();
Siggi Cherem (dart-lang) 2012/03/24 00:31:57 now that we made the distinction of main manager v
eub 2012/03/29 00:07:52 It looked like some of our code assumes that mainM
Siggi Cherem (dart-lang) 2012/03/29 00:24:49 probably, I wonder if that code is reachable (e.g.
eub 2012/03/29 21:20:44 Done.
87 _nativeInit(); 105 _nativeInit();
88 } 106 }
89 107
90 void _nativeInit() native @""" 108 void _nativeInit() native @"""
91 this.isWorker = typeof ($globalThis['importScripts']) != 'undefined'; 109 this.isWorker = typeof ($globalThis['importScripts']) != 'undefined';
92 this.inWindow = typeof(window) !== 'undefined'; 110 this.fromCommandLine = typeof(window) == 'undefined';
93 this.supportsWorkers = this.isWorker || 111 this.supportsWorkers = this.isWorker ||
94 ((typeof $globalThis['Worker']) != 'undefined'); 112 ((typeof $globalThis['Worker']) != 'undefined');
95 if (this.isWorker) { 113 if (this.isWorker) {
96 $globalThis.onmessage = function (e) { 114 $globalThis.onmessage = function (e) {
97 _IsolateNatives._processWorkerMessage(this.mainWorker, e); 115 _IsolateNatives._processWorkerMessage(this.mainManager, e);
98 }; 116 };
99 } 117 }
100 """ { 118 """ {
101 // Declare that the native code has a dependency on this fn. 119 // Declare that the native code has a dependency on this fn.
102 _IsolateNatives._processWorkerMessage(null, null); 120 _IsolateNatives._processWorkerMessage(null, null);
103 } 121 }
104 122
105 /** 123 /**
106 * Close the worker running this code, called when there is nothing else to 124 * Close the worker running this code if all isolates are done.
107 * run.
108 */ 125 */
109 void closeWorker() { 126 void maybeCloseWorker() {
110 if (isWorker) { 127 if (isolates.isEmpty()) {
111 if (!isolates.isEmpty()) return; 128 mainManager.postMessage(_serializeMessage({'command': 'close'}));
112 mainWorker.postMessage(
113 _serializeMessage({'command': 'close'}));
114 } else if (isolates.containsKey(rootContext.id) && workers.isEmpty() &&
115 !supportsWorkers && !inWindow) {
116 // This should only trigger when running on the command-line.
117 // We don't want this check to execute in the browser where the isolate
118 // might still be alive due to DOM callbacks.
119 throw new Exception("Program exited with open ReceivePorts.");
120 } 129 }
121 } 130 }
122 } 131 }
123 132
124 /** Context information tracked for each isolate. */ 133 /** Context information tracked for each isolate. */
125 class _IsolateContext { 134 class _IsolateContext {
126 /** Current isolate id. */ 135 /** Current isolate id. */
127 int id; 136 int id;
128 137
129 /** Registry of receive ports currently active on this isolate. */ 138 /** Registry of receive ports currently active on this isolate. */
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
195 204
196 _IsolateEvent dequeue() { 205 _IsolateEvent dequeue() {
197 if (events.isEmpty()) return null; 206 if (events.isEmpty()) return null;
198 return events.removeFirst(); 207 return events.removeFirst();
199 } 208 }
200 209
201 /** Process a single event, if any. */ 210 /** Process a single event, if any. */
202 bool runIteration() { 211 bool runIteration() {
203 final event = dequeue(); 212 final event = dequeue();
204 if (event == null) { 213 if (event == null) {
205 _globalState.closeWorker(); 214 if (_globalState.isWorker) {
215 _globalState.maybeCloseWorker();
216 } else if (_globalState.fromCommandLine &&
217 _globalState.rootContext.ports.isEmpty()) {
218 // XXX for iframes
219
220 // We want to reach here only on the main [_Manager] and
221 // only on the command-line. In the browser where the isolate
222 // might still be alive due to DOM callbacks, but the
223 // presumption is that on the command-line, no future events
224 // can be injected into the event queue once it's empty. Node
225 // has setTimeout so this presumption is incorrect there. We
226 // think(?) that in d8 this assumption is valid.
227 throw new Exception("Program exited with open ReceivePorts.");
228 }
206 return false; 229 return false;
207 } 230 }
208 event.process(); 231 event.process();
209 return true; 232 return true;
210 } 233 }
211 234
212 /** Function equivalent to [:window.setTimeout:] when available, or null. */ 235 /** Function equivalent to [:window.setTimeout:] when available, or null. */
213 static Function _wrapSetTimeout() native """ 236 static Function _wrapSetTimeout() native """
214 return typeof window != 'undefined' ? 237 return typeof window != 'undefined' ?
215 function(a, b) { window.setTimeout(a, b); } : undefined; 238 function(a, b) { window.setTimeout(a, b); } : undefined;
(...skipping 22 matching lines...) Expand all
238 * Call [_runHelper] but ensure that worker exceptions are propragated. Note 261 * Call [_runHelper] but ensure that worker exceptions are propragated. Note
239 * this is called from JavaScript (see $wrap_call in corejs.dart). 262 * this is called from JavaScript (see $wrap_call in corejs.dart).
240 */ 263 */
241 void run() { 264 void run() {
242 if (!_globalState.isWorker) { 265 if (!_globalState.isWorker) {
243 _runHelper(); 266 _runHelper();
244 } else { 267 } else {
245 try { 268 try {
246 _runHelper(); 269 _runHelper();
247 } catch(var e, var trace) { 270 } catch(var e, var trace) {
248 _globalState.mainWorker.postMessage(_serializeMessage( 271 _globalState.mainManager.postMessage(_serializeMessage(
249 {'command': 'error', 'msg': '$e\n$trace' })); 272 {'command': 'error', 'msg': '$e\n$trace' }));
250 } 273 }
251 } 274 }
252 } 275 }
253 } 276 }
254 277
255 /** An event in the top-level event queue. */ 278 /** An event in the top-level event queue. */
256 class _IsolateEvent { 279 class _IsolateEvent {
257 _IsolateContext isolate; 280 _IsolateContext isolate;
258 Function fn; 281 Function fn;
259 String message; 282 String message;
260 283
261 _IsolateEvent(this.isolate, this.fn, this.message); 284 _IsolateEvent(this.isolate, this.fn, this.message);
262 285
263 void process() { 286 void process() {
264 isolate.eval(fn); 287 isolate.eval(fn);
265 } 288 }
266 } 289 }
267 290
291 /** An interface for a stub used to interact with a manager. */
292 interface _ManagerStub {
293 get id();
294 void set id(int i);
295 void set onmessage(Function f);
296 void postMessage(msg);
297 void terminate();
298 }
268 299
269 /** Default worker. */ 300 /** A stub for interacting with the main manager. */
270 class _MainWorker { 301 class _MainManagerStub implements _ManagerStub {
271 int id = 0; 302 get id() => 0;
303 void set id(int i) { throw new NotImplementedException(); }
272 void postMessage(msg) native @"$globalThis.postMessage(msg);"; 304 void postMessage(msg) native @"$globalThis.postMessage(msg);";
273 void terminate() {} 305 void terminate() {} // Nothing useful to do here.
274 } 306 }
275 307
276 /** 308 /**
277 * A web worker. This type is also defined in 'dart:dom', but we define it here 309 * A stub for interacting with a manager built on a web worker. The type
278 * to avoid introducing a dependency from corelib to dom. This definition uses a 310 * Worker is also defined in 'dart:dom', but we define it here to avoid
311 * introducing a dependency from corelib to dom. This definition uses a
279 * 'hidden' type (* prefix on the native name) to enforce that the type is 312 * 'hidden' type (* prefix on the native name) to enforce that the type is
280 * defined dynamically only when web workers are actually available. 313 * defined dynamically only when web workers are actually available.
281 */ 314 */
282 class _Worker native "*Worker" { 315 class _WorkerStub implements _ManagerStub native "*Worker" {
283 get id() native "return this.id;"; 316 get id() native "return this.id;";
284 void set id(i) native "this.id = i;"; 317 void set id(i) native "this.id = i;";
285 void set onmessage(f) native "this.onmessage = f;"; 318 void set onmessage(f) native "this.onmessage = f;";
286 void postMessage(msg) native "return this.postMessage(msg);"; 319 void postMessage(msg) native "return this.postMessage(msg);";
320 // terminate() is implemented by Worker.
287 } 321 }
288 322
289 final String _SPAWNED_SIGNAL = "spawned"; 323 final String _SPAWNED_SIGNAL = "spawned";
290 324
291 class _IsolateNatives { 325 class _IsolateNatives {
292 326
293 /** JavaScript-specific implementation to spawn an isolate. */ 327 /** JavaScript-specific implementation to spawn an isolate. */
294 static Future<SendPort> spawn(Isolate isolate, bool isLight) { 328 static Future<SendPort> spawn(Isolate isolate, bool isLight) {
295 Completer<SendPort> completer = new Completer<SendPort>(); 329 Completer<SendPort> completer = new Completer<SendPort>();
296 ReceivePort port = new ReceivePort.singleShot(); 330 ReceivePort port = new ReceivePort.singleShot();
297 port.receive((msg, SendPort replyPort) { 331 port.receive((msg, SendPort replyPort) {
298 assert(msg == _SPAWNED_SIGNAL); 332 assert(msg == _SPAWNED_SIGNAL);
299 completer.complete(replyPort); 333 completer.complete(replyPort);
300 }); 334 });
301 335
302 // TODO(floitsch): throw exception if isolate's class doesn't have a 336 // TODO(floitsch): throw exception if isolate's class doesn't have a
303 // default constructor. 337 // default constructor.
304 if (_globalState.useWorkers && !isLight) { 338 if (_globalState.useWorkers && !isLight) {
305 _startWorker(isolate, port.toSendPort()); 339 _startWorker(isolate, port.toSendPort());
306 } else { 340 } else {
307 _startNonWorker(isolate, port.toSendPort()); 341 _startNonWorker(isolate, port.toSendPort());
308 } 342 }
309 343
310 return completer.future; 344 return completer.future;
311 } 345 }
312 346
313 static SendPort _startWorker(Isolate runnable, SendPort replyPort) { 347 static SendPort _startWorker(Isolate runnable, SendPort replyPort) {
314 var factoryName = _getJSConstructorName(runnable); 348 var factoryName = _getJSConstructorName(runnable);
315 if (_globalState.isWorker) { 349 if (_globalState.isWorker) {
316 _globalState.mainWorker.postMessage(_serializeMessage({ 350 _globalState.mainManager.postMessage(_serializeMessage({
317 'command': 'spawn-worker', 351 'command': 'spawn-worker',
318 'factoryName': factoryName, 352 'factoryName': factoryName,
319 'replyPort': _serializeMessage(replyPort)})); 353 'replyPort': _serializeMessage(replyPort)}));
320 } else { 354 } else {
321 _spawnWorker(factoryName, _serializeMessage(replyPort)); 355 _spawnWorker(factoryName, _serializeMessage(replyPort));
322 } 356 }
323 } 357 }
324 358
325 /** 359 /**
326 * The src url for the script tag that loaded this code. Used to create 360 * The src url for the script tag that loaded this code. Used to create
(...skipping 22 matching lines...) Expand all
349 var src = script && script.src; 383 var src = script && script.src;
350 if (!src) { 384 if (!src) {
351 // TODO() 385 // TODO()
352 src = "FIXME:5407062" + "_" + Math.random().toString(); 386 src = "FIXME:5407062" + "_" + Math.random().toString();
353 if (script) script.src = src; 387 if (script) script.src = src;
354 } 388 }
355 return src; 389 return src;
356 """; 390 """;
357 391
358 /** Starts a new worker with the given URL. */ 392 /** Starts a new worker with the given URL. */
359 static _Worker _newWorker(url) native "return new Worker(url);"; 393 static _WorkerStub _newWorker(url) native "return new Worker(url);";
360 394
361 /** 395 /**
362 * Spawns an isolate in a worker. [factoryName] is the Javascript constructor 396 * Spawns an isolate in a worker. [factoryName] is the Javascript constructor
363 * name for the isolate entry point class. 397 * name for the isolate entry point class.
364 */ 398 */
365 static void _spawnWorker(factoryName, serializedReplyPort) { 399 static void _spawnWorker(factoryName, serializedReplyPort) {
366 final worker = _newWorker(_thisScript); 400 final worker = _newWorker(_thisScript);
367 worker.onmessage = (e) { _processWorkerMessage(worker, e); }; 401 worker.onmessage = (e) { _processWorkerMessage(worker, e); };
368 var workerId = _globalState.nextWorkerId++; 402 var workerId = _globalState.nextManagerId++;
369 // We also store the id on the worker itself so that we can unregister it. 403 // We also store the id on the worker itself so that we can unregister it.
370 worker.id = workerId; 404 worker.id = workerId;
371 _globalState.workers[workerId] = worker; 405 _globalState.managers[workerId] = worker;
372 worker.postMessage(_serializeMessage({ 406 worker.postMessage(_serializeMessage({
373 'command': 'start', 407 'command': 'start',
374 'id': workerId, 408 'id': workerId,
375 'replyTo': serializedReplyPort, 409 'replyTo': serializedReplyPort,
376 'factoryName': factoryName })); 410 'factoryName': factoryName }));
377 } 411 }
378 412
379 /** 413 /**
380 * Assume that [e] is a browser message event and extract its message data. 414 * Assume that [e] is a browser message event and extract its message data.
381 * We don't import the dom explicitly so, when workers are disabled, this 415 * We don't import the dom explicitly so, when workers are disabled, this
382 * library can also run on top of nodejs. 416 * library can also run on top of nodejs.
383 */ 417 */
384 static _getEventData(e) native "return e.data"; 418 static _getEventData(e) native "return e.data";
385 419
386 /** 420 /**
387 * Process messages on a worker, either to control the worker instance or to 421 * Process messages on a worker, either to control the worker instance or to
388 * pass messages along to the isolate running in the worker. 422 * pass messages along to the isolate running in the worker.
389 */ 423 */
390 static void _processWorkerMessage(sender, e) { 424 static void _processWorkerMessage(sender, e) {
391 var msg = _deserializeMessage(_getEventData(e)); 425 var msg = _deserializeMessage(_getEventData(e));
392 switch (msg['command']) { 426 switch (msg['command']) {
393 // TODO(sigmund): delete after we migrate to the new API 427 // TODO(sigmund): delete after we migrate to the new API
394 case 'start': 428 case 'start':
395 _globalState.currentWorkerId = msg['id']; 429 _globalState.currentManagerId = msg['id'];
396 var runnerObject = 430 var runnerObject =
397 _allocate(_getJSConstructorFromName(msg['factoryName'])); 431 _allocate(_getJSConstructorFromName(msg['factoryName']));
398 var serializedReplyTo = msg['replyTo']; 432 var serializedReplyTo = msg['replyTo'];
399 _globalState.topEventLoop.enqueue(new _IsolateContext(), function() { 433 _globalState.topEventLoop.enqueue(new _IsolateContext(), function() {
400 var replyTo = _deserializeMessage(serializedReplyTo); 434 var replyTo = _deserializeMessage(serializedReplyTo);
401 _startIsolate(runnerObject, replyTo); 435 _startIsolate(runnerObject, replyTo);
402 }, 'worker-start'); 436 }, 'worker-start');
403 _globalState.topEventLoop.run(); 437 _globalState.topEventLoop.run();
404 break; 438 break;
405 case 'start2': 439 case 'start2':
406 _globalState.currentWorkerId = msg['id']; 440 _globalState.currentManagerId = msg['id'];
407 Function entryPoint = _getJSFunctionFromName(msg['functionName']); 441 Function entryPoint = _getJSFunctionFromName(msg['functionName']);
408 var replyTo = _deserializeMessage(msg['replyTo']); 442 var replyTo = _deserializeMessage(msg['replyTo']);
409 _globalState.topEventLoop.enqueue(new _IsolateContext(), function() { 443 _globalState.topEventLoop.enqueue(new _IsolateContext(), function() {
410 _startIsolate2(entryPoint, replyTo); 444 _startIsolate2(entryPoint, replyTo);
411 }, 'worker-start'); 445 }, 'worker-start');
412 _globalState.topEventLoop.run(); 446 _globalState.topEventLoop.run();
413 break; 447 break;
414 // TODO(sigmund): delete after we migrate to the new API 448 // TODO(sigmund): delete after we migrate to the new API
415 case 'spawn-worker': 449 case 'spawn-worker':
416 _spawnWorker(msg['factoryName'], msg['replyPort']); 450 _spawnWorker(msg['factoryName'], msg['replyPort']);
417 break; 451 break;
418 case 'spawn-worker2': 452 case 'spawn-worker2':
419 _spawnWorker2(msg['functionName'], msg['uri'], msg['replyPort']); 453 _spawnWorker2(msg['functionName'], msg['uri'], msg['replyPort']);
420 break; 454 break;
421 case 'message': 455 case 'message':
422 msg['port'].send(msg['msg'], msg['replyTo']); 456 msg['port'].send(msg['msg'], msg['replyTo']);
423 _globalState.topEventLoop.run(); 457 _globalState.topEventLoop.run();
424 break; 458 break;
425 case 'close': 459 case 'close':
426 _log("Closing Worker"); 460 _log("Closing Worker");
427 _globalState.workers.remove(sender.id); 461 _globalState.managers.remove(sender.id);
428 sender.terminate(); 462 sender.terminate();
429 _globalState.topEventLoop.run(); 463 _globalState.topEventLoop.run();
430 break; 464 break;
431 case 'log': 465 case 'log':
432 _log(msg['msg']); 466 _log(msg['msg']);
433 break; 467 break;
434 case 'print': 468 case 'print':
435 if (_globalState.isWorker) { 469 if (_globalState.isWorker) {
436 _globalState.mainWorker.postMessage( 470 _globalState.mainManager.postMessage(
437 _serializeMessage({'command': 'print', 'msg': msg})); 471 _serializeMessage({'command': 'print', 'msg': msg}));
438 } else { 472 } else {
439 print(msg['msg']); 473 print(msg['msg']);
440 } 474 }
441 break; 475 break;
442 case 'error': 476 case 'error':
443 throw msg['msg']; 477 throw msg['msg'];
444 } 478 }
445 } 479 }
446 480
447 /** Log a message, forwarding to the main worker if appropriate. */ 481 /** Log a message, forwarding to the main [_Manager] if appropriate. */
448 static _log(msg) { 482 static _log(msg) {
449 if (_globalState.isWorker) { 483 if (_globalState.isWorker) {
450 _globalState.mainWorker.postMessage( 484 _globalState.mainManager.postMessage(
451 _serializeMessage({'command': 'log', 'msg': msg })); 485 _serializeMessage({'command': 'log', 'msg': msg }));
452 } else { 486 } else {
453 try { 487 try {
454 _consoleLog(msg); 488 _consoleLog(msg);
455 } catch(e, trace) { 489 } catch(e, trace) {
456 throw new Exception(trace); 490 throw new Exception(trace);
457 } 491 }
458 } 492 }
459 } 493 }
460 494
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
556 } else { 590 } else {
557 _startNonWorker2(functionName, uri, signalReply); 591 _startNonWorker2(functionName, uri, signalReply);
558 } 592 }
559 return new _BufferingSendPort( 593 return new _BufferingSendPort(
560 _globalState.currentContext.id, completer.future); 594 _globalState.currentContext.id, completer.future);
561 } 595 }
562 596
563 static SendPort _startWorker2( 597 static SendPort _startWorker2(
564 String functionName, String uri, SendPort replyPort) { 598 String functionName, String uri, SendPort replyPort) {
565 if (_globalState.isWorker) { 599 if (_globalState.isWorker) {
566 _globalState.mainWorker.postMessage(_serializeMessage({ 600 _globalState.mainManager.postMessage(_serializeMessage({
567 'command': 'spawn-worker2', 601 'command': 'spawn-worker2',
568 'functionName': functionName, 602 'functionName': functionName,
569 'uri': uri, 603 'uri': uri,
570 'replyPort': replyPort})); 604 'replyPort': replyPort}));
571 } else { 605 } else {
572 _spawnWorker2(functionName, uri, replyPort); 606 _spawnWorker2(functionName, uri, replyPort);
573 } 607 }
574 } 608 }
575 609
576 static SendPort _startNonWorker2( 610 static SendPort _startNonWorker2(
(...skipping 22 matching lines...) Expand all
599 if (functionName == null) functionName = 'main'; 633 if (functionName == null) functionName = 'main';
600 if (uri == null) uri = _thisScript; 634 if (uri == null) uri = _thisScript;
601 if (!(new Uri.fromString(uri).isAbsolute())) { 635 if (!(new Uri.fromString(uri).isAbsolute())) {
602 // The constructor of dom workers requires an absolute URL. If we use a 636 // The constructor of dom workers requires an absolute URL. If we use a
603 // relative path we will get a DOM exception. 637 // relative path we will get a DOM exception.
604 String prefix = _thisScript.substring(0, _thisScript.lastIndexOf('/')); 638 String prefix = _thisScript.substring(0, _thisScript.lastIndexOf('/'));
605 uri = "$prefix/$uri"; 639 uri = "$prefix/$uri";
606 } 640 }
607 final worker = _newWorker(uri); 641 final worker = _newWorker(uri);
608 worker.onmessage = (e) { _processWorkerMessage(worker, e); }; 642 worker.onmessage = (e) { _processWorkerMessage(worker, e); };
609 var workerId = _globalState.nextWorkerId++; 643 var workerId = _globalState.nextManagerId++;
610 // We also store the id on the worker itself so that we can unregister it. 644 // We also store the id on the worker itself so that we can unregister it.
611 worker.id = workerId; 645 worker.id = workerId;
612 _globalState.workers[workerId] = worker; 646 _globalState.managers[workerId] = worker;
613 worker.postMessage(_serializeMessage({ 647 worker.postMessage(_serializeMessage({
614 'command': 'start2', 648 'command': 'start2',
615 'id': workerId, 649 'id': workerId,
616 // Note: we serialize replyPort twice because the child worker needs to 650 // Note: we serialize replyPort twice because the child worker needs to
617 // first deserialize the worker id, before it can correctly deserialize 651 // first deserialize the worker id, before it can correctly deserialize
618 // the port (port deserialization is sensitive to what is the current 652 // the port (port deserialization is sensitive to what is the current
619 // workerId). 653 // workerId).
620 'replyTo': _serializeMessage(replyPort), 654 'replyTo': _serializeMessage(replyPort),
621 'functionName': functionName })); 655 'functionName': functionName }));
622 } 656 }
623 } 657 }
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