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

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

Issue 9358010: isolates in frog: playing with API improvements (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: '' Created 8 years, 10 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
OLDNEW
1 // Copyright (c) 2011, 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 * A native object that is shared across isolates. This object is visible to all 6 * 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). 7 * isolates running on the same worker (either UI or background web worker).
8 * 8 *
9 * This is code that is intended to 'escape' the isolate boundaries in order to 9 * This is code that is intended to 'escape' the isolate boundaries in order to
10 * implement the semantics of friendly isolates in JavaScript. Without this we 10 * implement the semantics of friendly isolates in JavaScript. Without this we
11 * would have been forced to implement more code (including the top-level event 11 * would have been forced to implement more code (including the top-level event
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
155 155
156 _deserializeMessage(message) { 156 _deserializeMessage(message) {
157 if (_globalState.needSerialization) { 157 if (_globalState.needSerialization) {
158 return new Deserializer().deserialize(message); 158 return new Deserializer().deserialize(message);
159 } else { 159 } else {
160 // Nothing more to do. 160 // Nothing more to do.
161 return message; 161 return message;
162 } 162 }
163 } 163 }
164 164
165 /** Wait until all ports in a message are resolved. */
166 _waitForPendingPorts(var message, void callback()) {
167 final finder = new PendingSendPortFinder();
168 finder.traverse(message);
169 Futures.wait(finder.ports).then((_) => callback());
170 }
171
165 /** Default worker. */ 172 /** Default worker. */
166 class MainWorker { 173 class MainWorker {
167 int id = 0; 174 int id = 0;
168 void postMessage(msg) native "return \$globalThis.postMessage(msg);"; 175 void postMessage(msg) native "return \$globalThis.postMessage(msg);";
169 void set onmessage(f) native "\$globalThis.onmessage = f;"; 176 void set onmessage(f) native "\$globalThis.onmessage = f;";
170 void terminate() {} 177 void terminate() {}
171 } 178 }
172 179
173 /** 180 /**
174 * A web worker. This type is also defined in 'dart:dom', but we define it here 181 * A web worker. This type is also defined in 'dart:dom', but we define it here
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
333 340
334 BaseSendPort(this._isolateId); 341 BaseSendPort(this._isolateId);
335 342
336 ReceivePortSingleShotImpl call(var message) { 343 ReceivePortSingleShotImpl call(var message) {
337 final result = new ReceivePortSingleShotImpl(); 344 final result = new ReceivePortSingleShotImpl();
338 this.send(message, result.toSendPort()); 345 this.send(message, result.toSendPort());
339 return result; 346 return result;
340 } 347 }
341 348
342 static void checkReplyTo(SendPort replyTo) { 349 static void checkReplyTo(SendPort replyTo) {
343 if (replyTo !== null && replyTo is! NativeJsSendPort 350 if (replyTo !== null
344 && replyTo is! WorkerSendPort) { 351 && replyTo is! NativeJsSendPort
345 throw "SendPort.send: Illegal replyTo port type."; 352 && replyTo is! WorkerSendPort
353 && replyTo is! BufferingSendPort) {
354 throw new Exception("SendPort.send: Illegal replyTo port type");
346 } 355 }
347 } 356 }
348 357
349 // TODO(sigmund): replace the current SendPort.call with the following: 358 // TODO(sigmund): replace the current SendPort.call with the following:
350 //Future call(var message) { 359 //Future call(var message) {
351 //  final completer = new Completer(); 360 //  final completer = new Completer();
352 //  final port = new ReceivePort.singleShot(); 361 //  final port = new ReceivePort.singleShot();
353 //  send(message, port.toSendPort()); 362 //  send(message, port.toSendPort());
354 //  port.receive((value, ignoreReplyTo) { 363 //  port.receive((value, ignoreReplyTo) {
355 //    if (value is Exception) { 364 //    if (value is Exception) {
(...skipping 10 matching lines...) Expand all
366 abstract int hashCode(); 375 abstract int hashCode();
367 } 376 }
368 377
369 /** A send port that delivers messages in-memory via native JavaScript calls. */ 378 /** A send port that delivers messages in-memory via native JavaScript calls. */
370 class NativeJsSendPort extends BaseSendPort implements SendPort { 379 class NativeJsSendPort extends BaseSendPort implements SendPort {
371 final ReceivePortImpl _receivePort; 380 final ReceivePortImpl _receivePort;
372 381
373 const NativeJsSendPort(this._receivePort, int isolateId) : super(isolateId); 382 const NativeJsSendPort(this._receivePort, int isolateId) : super(isolateId);
374 383
375 void send(var message, [SendPort replyTo = null]) { 384 void send(var message, [SendPort replyTo = null]) {
376 checkReplyTo(replyTo); 385 _waitForPendingPorts([message, replyTo], () {
377 // Check that the isolate still runs and the port is still open 386 checkReplyTo(replyTo);
378 final isolate = _globalState.isolates[_isolateId]; 387 // Check that the isolate still runs and the port is still open
379 if (isolate == null) return; 388 final isolate = _globalState.isolates[_isolateId];
380 if (_receivePort._callback == null) return; 389 if (isolate == null) return;
390 if (_receivePort._callback == null) return;
381 391
382 // We force serialization/deserialization as a simple way to ensure isolate 392 // We force serialization/deserialization as a simple way to ensure isolat e
eub 2012/02/10 22:46:19 Line length?
Siggi Cherem (dart-lang) 2012/02/10 23:42:22 Done.
383 // communication restrictions are respected between isolates that live in 393 // communication restrictions are respected between isolates that live in
384 // the same worker. NativeJsSendPort delivers both messages from the same 394 // the same worker. NativeJsSendPort delivers both messages from the same
385 // worker and messages from other workers. In particular, messages sent from 395 // worker and messages from other workers. In particular, messages sent fr om
386 // a worker via a WorkerSendPort are received at [_processWorkerMessage] and 396 // a worker via a WorkerSendPort are received at [_processWorkerMessage] a nd
387 // forwarded to a native port. In such cases, here we'll see 397 // forwarded to a native port. In such cases, here we'll see
388 // [_globalState.currentContext == null]. 398 // [_globalState.currentContext == null].
389 final shouldSerialize = _globalState.currentContext != null 399 final shouldSerialize = _globalState.currentContext != null
390 && _globalState.currentContext.id != _isolateId; 400 && _globalState.currentContext.id != _isolateId;
391 var msg = message; 401 var msg = message;
392 var reply = replyTo; 402 var reply = replyTo;
393 if (shouldSerialize) { 403 if (shouldSerialize) {
394 msg = _serializeMessage(msg); 404 msg = _serializeMessage(msg);
395 reply = _serializeMessage(reply); 405 reply = _serializeMessage(reply);
396 } 406 }
397 _globalState.topEventLoop.enqueue(isolate, () { 407 _globalState.topEventLoop.enqueue(isolate, () {
398 if (_receivePort._callback != null) { 408 if (_receivePort._callback != null) {
399 if (shouldSerialize) { 409 if (shouldSerialize) {
400 msg = _deserializeMessage(msg); 410 msg = _deserializeMessage(msg);
401 reply = _deserializeMessage(reply); 411 reply = _deserializeMessage(reply);
412 }
413 _receivePort._callback(msg, reply);
402 } 414 }
403 _receivePort._callback(msg, reply); 415 }, 'receive ' + message);
404 } 416 });
405 }, 'receive ' + message);
406 } 417 }
407 418
408 bool operator ==(var other) => (other is NativeJsSendPort) && 419 bool operator ==(var other) => (other is NativeJsSendPort) &&
409 (_receivePort == other._receivePort); 420 (_receivePort == other._receivePort);
410 421
411 int hashCode() => _receivePort._id; 422 int hashCode() => _receivePort._id;
412 } 423 }
413 424
414 /** A send port that delivers messages via worker.postMessage. */ 425 /** A send port that delivers messages via worker.postMessage. */
415 class WorkerSendPort extends BaseSendPort implements SendPort { 426 class WorkerSendPort extends BaseSendPort implements SendPort {
416 final int _workerId; 427 final int _workerId;
417 final int _receivePortId; 428 final int _receivePortId;
418 429
419 const WorkerSendPort(this._workerId, int isolateId, this._receivePortId) 430 const WorkerSendPort(this._workerId, int isolateId, this._receivePortId)
420 : super(isolateId); 431 : super(isolateId);
421 432
422 void send(var message, [SendPort replyTo = null]) { 433 void send(var message, [SendPort replyTo = null]) {
423 checkReplyTo(replyTo); 434 _waitForPendingPorts([message, replyTo], () {
424 final workerMessage = _serializeMessage({ 435 checkReplyTo(replyTo);
425 'command': 'message', 436 final workerMessage = _serializeMessage({
426 'port': this, 437 'command': 'message',
427 'msg': message, 438 'port': _serializeMessage(this),
428 'replyTo': replyTo}); 439 'msg': message,
440 'replyTo': _serializeMessage(replyTo)});
429 441
430 if (_globalState.isWorker) { 442 if (_globalState.isWorker) {
431 // communication from one worker to another go through the main worker: 443 // communication from one worker to another go through the main worker:
432 _globalState.mainWorker.postMessage(workerMessage); 444 _globalState.mainWorker.postMessage(workerMessage);
433 } else { 445 } else {
434 _globalState.workers[_workerId].postMessage(workerMessage); 446 _globalState.workers[_workerId].postMessage(workerMessage);
435 } 447 }
448 });
436 } 449 }
437 450
438 bool operator ==(var other) { 451 bool operator ==(var other) {
439 return (other is WorkerSendPort) && 452 return (other is WorkerSendPort) &&
440 (_workerId == other._workerId) && 453 (_workerId == other._workerId) &&
441 (_isolateId == other._isolateId) && 454 (_isolateId == other._isolateId) &&
442 (_receivePortId == other._receivePortId); 455 (_receivePortId == other._receivePortId);
443 } 456 }
444 457
445 int hashCode() { 458 int hashCode() {
446 // TODO(sigmund): use a standard hash when we get one available in corelib. 459 // TODO(sigmund): use a standard hash when we get one available in corelib.
447 return (_workerId << 16) ^ (_isolateId << 8) ^ _receivePortId; 460 return (_workerId << 16) ^ (_isolateId << 8) ^ _receivePortId;
448 } 461 }
449 } 462 }
450 463
464 /** A port that buffers messages until an underlying port gets resolve. */
eub 2012/02/10 22:46:19 ("resolved")
Siggi Cherem (dart-lang) 2012/02/10 23:42:22 Done.
465 class BufferingSendPort extends BaseSendPort implements SendPort {
466 static int _bufferingCount = 0;
eub 2012/02/10 22:46:19 A comment, please.
Siggi Cherem (dart-lang) 2012/02/10 23:42:22 Done.
467
468 /** For implementing equals and hashcode. */
469 final int id;
eub 2012/02/10 22:46:19 Why public?
Siggi Cherem (dart-lang) 2012/02/10 23:42:22 no reason. done
470
471 /** Underlying port, when resolved. */
472 SendPort _port;
473
474 /**
475 * Future of the underlying port, so that we can detect when this port can be
476 * sent on messages.
477 */
478 Future<SendPort> _futurePort;
479
480 /** Pending messages (and reply ports). */
481 List pending;
482
483 BufferingSendPort(isolateId, this._futurePort)
484 : super(isolateId), id = _bufferingCount, pending = [] {
485 _bufferingCount++;
eub 2012/02/10 22:46:19 id = _bufferingCount++ ? or a static fn that expos
Siggi Cherem (dart-lang) 2012/02/10 23:42:22 Unfortunately, if I move the id initialization her
486 _futurePort.then((p) {
487 _port = p;
488 for (final message in pending) {
489 p.send(message[0], message[1]);
eub 2012/02/10 22:46:19 Raw access to numeric indices is oogy.
Siggi Cherem (dart-lang) 2012/02/10 23:42:22 Done - made into a map record.
490 }
491 pending = null;
492 });
493 }
494
495 BufferingSendPort.fromPort(isolateId, this._port)
496 : super(isolateId), id = _bufferingCount {
497 _bufferingCount++;
498 }
499
500 void send(var message, [SendPort replyTo]) {
501 if (_port != null) {
502 _port.send(message, replyTo);
503 } else {
504 pending.add([message, replyTo]);
505 }
506 }
507
508 bool operator ==(var other) => (other is BufferingSendPort && id == other.id);
509 int hashCode() => id;
510 }
511
451 /** Default factory for receive ports. */ 512 /** Default factory for receive ports. */
452 class ReceivePortFactory { 513 class ReceivePortFactory {
453 514
454 factory ReceivePort() { 515 factory ReceivePort() {
455 return new ReceivePortImpl(); 516 return new ReceivePortImpl();
456 } 517 }
457 518
458 factory ReceivePort.singleShot() { 519 factory ReceivePort.singleShot() {
459 return new ReceivePortSingleShotImpl(); 520 return new ReceivePortSingleShotImpl();
460 } 521 }
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
529 590
530 return completer.future; 591 return completer.future;
531 } 592 }
532 593
533 static SendPort _startWorker(Isolate runnable, SendPort replyPort) { 594 static SendPort _startWorker(Isolate runnable, SendPort replyPort) {
534 var factoryName = _getJSConstructorName(runnable); 595 var factoryName = _getJSConstructorName(runnable);
535 if (_globalState.isWorker) { 596 if (_globalState.isWorker) {
536 _globalState.mainWorker.postMessage(_serializeMessage({ 597 _globalState.mainWorker.postMessage(_serializeMessage({
537 'command': 'spawn-worker', 598 'command': 'spawn-worker',
538 'factoryName': factoryName, 599 'factoryName': factoryName,
539 'replyPort': replyPort})); 600 'replyPort': _serializeMessage(replyPort)}));
540 } else { 601 } else {
541 _spawnWorker(factoryName, _serializeMessage(replyPort)); 602 _spawnWorker(factoryName, _serializeMessage(replyPort));
542 } 603 }
543 } 604 }
544 605
545
546 /** 606 /**
547 * The src url for the script tag that loaded this code. Used to create 607 * The src url for the script tag that loaded this code. Used to create
548 * JavaScript workers. 608 * JavaScript workers.
549 */ 609 */
550 static String get _thisScript() => 610 static String get _thisScript() =>
551 _thisScriptCache != null ? _thisScriptCache : _computeThisScript(); 611 _thisScriptCache != null ? _thisScriptCache : _computeThisScript();
552 612
553 static String _thisScriptCache; 613 static String _thisScriptCache;
554 614
555 // TODO(sigmund): fix - this code should be run synchronously when loading the 615 // TODO(sigmund): fix - this code should be run synchronously when loading the
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
601 */ 661 */
602 static _getEventData(e) native "return e.data"; 662 static _getEventData(e) native "return e.data";
603 663
604 /** 664 /**
605 * Process messages on a worker, either to control the worker instance or to 665 * Process messages on a worker, either to control the worker instance or to
606 * pass messages along to the isolate running in the worker. 666 * pass messages along to the isolate running in the worker.
607 */ 667 */
608 static void _processWorkerMessage(sender, e) { 668 static void _processWorkerMessage(sender, e) {
609 var msg = _deserializeMessage(_getEventData(e)); 669 var msg = _deserializeMessage(_getEventData(e));
610 switch (msg['command']) { 670 switch (msg['command']) {
671 // TODO(sigmund): delete after we migrate to Isolate2
611 case 'start': 672 case 'start':
612 _globalState.currentWorkerId = msg['id']; 673 _globalState.currentWorkerId = msg['id'];
613 var runnerObject = 674 var runnerObject =
614 _allocate(_getJSConstructorFromName(msg['factoryName'])); 675 _allocate(_getJSConstructorFromName(msg['factoryName']));
615 var serializedReplyTo = msg['replyTo']; 676 var serializedReplyTo = msg['replyTo'];
616 _globalState.topEventLoop.enqueue(new IsolateContext(), function() { 677 _globalState.topEventLoop.enqueue(new IsolateContext(), function() {
617 var replyTo = _deserializeMessage(serializedReplyTo); 678 var replyTo = _deserializeMessage(serializedReplyTo);
618 IsolateNatives._startIsolate(runnerObject, replyTo); 679 _startIsolate(runnerObject, replyTo);
619 }, 'worker-start'); 680 }, 'worker-start');
620 _globalState.topEventLoop.run(); 681 _globalState.topEventLoop.run();
621 break; 682 break;
683 case 'start2':
684 _globalState.currentWorkerId = msg['id'];
685 Function entryPoint = _getJSFunctionFromName(msg['functionName']);
686 var replyTo = _deserializeMessage(msg['replyTo']);
687 _globalState.topEventLoop.enqueue(new IsolateContext(), function() {
688 _startIsolate2(entryPoint, replyTo);
689 }, 'worker-start');
690 _globalState.topEventLoop.run();
691 break;
692 // TODO(sigmund): delete after we migrate to Isolate2
622 case 'spawn-worker': 693 case 'spawn-worker':
623 _spawnWorker(msg['factoryName'], msg['replyPort']); 694 _spawnWorker(msg['factoryName'], msg['replyPort']);
624 break; 695 break;
696 case 'spawn-worker2':
697 _spawnWorker2(msg['functionName'], msg['uri'], msg['replyPort']);
698 break;
625 case 'message': 699 case 'message':
626 msg['port'].send(msg['msg'], msg['replyTo']); 700 final iid = _globalState.currentContext == null ? '?' : '${_globalState. currentContext.id }';
eub 2012/02/10 22:46:19 Dead code?
Siggi Cherem (dart-lang) 2012/02/10 23:42:22 yep, done.
701 final port = _deserializeMessage(msg['port']);
702 port.send(msg['msg'], _deserializeMessage(msg['replyTo']));
627 _globalState.topEventLoop.run(); 703 _globalState.topEventLoop.run();
628 break; 704 break;
629 case 'close': 705 case 'close':
630 _log("Closing Worker"); 706 _log("Closing Worker");
631 _globalState.workers.remove(sender.id); 707 _globalState.workers.remove(sender.id);
632 sender.terminate(); 708 sender.terminate();
633 _globalState.topEventLoop.run(); 709 _globalState.topEventLoop.run();
634 break; 710 break;
635 case 'log': 711 case 'log':
636 _log(msg['msg']); 712 _log(msg['msg']);
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
677 // TODO(sigmund): find a browser-generic way to support this. 753 // TODO(sigmund): find a browser-generic way to support this.
678 static var _getJSConstructorName(Isolate runnable) native """ 754 static var _getJSConstructorName(Isolate runnable) native """
679 return runnable.constructor.name; 755 return runnable.constructor.name;
680 """; 756 """;
681 757
682 /** Find a constructor given it's name. */ 758 /** Find a constructor given it's name. */
683 static var _getJSConstructorFromName(String factoryName) native """ 759 static var _getJSConstructorFromName(String factoryName) native """
684 return \$globalThis[factoryName]; 760 return \$globalThis[factoryName];
685 """; 761 """;
686 762
763 static var _getJSFunctionFromName(String functionName) native """
764 return \$globalThis[functionName];
765 """;
766
767 static String _getJSFunctionName(Function f) native "return f.name || null;";
768
687 /** Create a new JavasSript object instance given it's constructor. */ 769 /** Create a new JavasSript object instance given it's constructor. */
688 static var _allocate(var ctor) native "return new ctor();"; 770 static var _allocate(var ctor) native "return new ctor();";
689 771
690 /** Starts a non-worker isolate. */ 772 /** Starts a non-worker isolate. */
691 static SendPort _startNonWorker(Isolate runnable, SendPort replyTo) { 773 static SendPort _startNonWorker(Isolate runnable, SendPort replyTo) {
692 // Spawn a new isolate and create the receive port in it. 774 // Spawn a new isolate and create the receive port in it.
693 final spawned = new IsolateContext(); 775 final spawned = new IsolateContext();
694 776
695 // Instead of just running the provided runnable, we create a 777 // Instead of just running the provided runnable, we create a
696 // new cloned instance of it with a fresh state in the spawned 778 // new cloned instance of it with a fresh state in the spawned
697 // isolate. This way, we do not get cross-isolate references 779 // isolate. This way, we do not get cross-isolate references
698 // through the runnable. 780 // through the runnable.
699 final ctor = _getJSConstructor(runnable); 781 final ctor = _getJSConstructor(runnable);
700 _globalState.topEventLoop.enqueue(spawned, function() { 782 _globalState.topEventLoop.enqueue(spawned, function() {
701 _startIsolate(_allocate(ctor), replyTo); 783 _startIsolate(_allocate(ctor), replyTo);
702 }, 'nonworker start'); 784 }, 'nonworker start');
703 } 785 }
704 786
705 /** Given a ready-to-start runnable, start running it. */ 787 /** Given a ready-to-start runnable, start running it. */
706 static void _startIsolate(Isolate isolate, SendPort replyTo) { 788 static void _startIsolate(Isolate isolate, SendPort replyTo) {
707 _fillStatics(_globalState.currentContext); 789 _fillStatics(_globalState.currentContext);
708 ReceivePort port = new ReceivePort(); 790 ReceivePort port = new ReceivePort();
709 replyTo.send(_SPAWNED_SIGNAL, port.toSendPort()); 791 replyTo.send(_SPAWNED_SIGNAL, port.toSendPort());
710 isolate._run(port); 792 isolate._run(port);
711 } 793 }
794
795 // TODO(sigmund): clean up above, after we make the new API the default:
796
797 static _spawn2(String functionName, String uri, bool isLight) {
798 Completer<SendPort> completer = new Completer<SendPort>();
799 ReceivePort port = new ReceivePort.singleShot();
800 port.receive((msg, SendPort replyPort) {
801 assert(msg == _SPAWNED_SIGNAL);
802 completer.complete(replyPort);
803 });
804
805 SendPort signalReply = port.toSendPort();
806
807 if (_globalState.useWorkers && !isLight) {
808 _startWorker2(functionName, uri, signalReply);
809 } else {
810 _startNonWorker2(functionName, uri, signalReply);
811 }
812 return new BufferingSendPort(
813 _globalState.currentContext.id, completer.future);
814 }
815
816 static SendPort _startWorker2(
817 String functionName, String uri, SendPort replyPort) {
818 if (_globalState.isWorker) {
819 _globalState.mainWorker.postMessage(_serializeMessage({
820 'command': 'spawn-worker2',
821 'functionName': functionName,
822 'uri': uri,
823 'replyPort': replyPort}));
824 } else {
825 _spawnWorker2(functionName, uri, replyPort);
826 }
827 }
828
829 static SendPort _startNonWorker2(
830 String functionName, String uri, SendPort replyPort) {
831 _globalState.topEventLoop.enqueue(new IsolateContext(), function() {
832 final func = _getJSFunctionFromName(functionName);
833 _startIsolate2(func, replyPort);
834 }, 'nonworker start');
835 }
836
837 static void _startIsolate2(Function topLevel, SendPort replyTo) {
838 _fillStatics(_globalState.currentContext);
839 final port = new ReceivePort();
840 replyTo.send(_SPAWNED_SIGNAL, port.toSendPort());
841 topLevel(port);
842 }
843
844 /**
845 * Spawns an isolate in a worker. [factoryName] is the Javascript constructor
846 * name for the isolate entry point class.
847 */
848 static void _spawnWorker2(functionName, uri, replyPort) {
849 if (uri == null) uri = _thisScript;
850 final worker = _newWorker(uri);
851 worker.onmessage = (e) { _processWorkerMessage(worker, e); };
852 var workerId = _globalState.nextWorkerId++;
853 // We also store the id on the worker itself so that we can unregister it.
854 worker.id = workerId;
855 _globalState.workers[workerId] = worker;
856 worker.postMessage(_serializeMessage({
857 'command': 'start2',
858 'id': workerId,
859 // Note: we serialize replyPort twice because the child worker needs to
860 // first deserialize the worker id, before it can correctly deserialize
861 // the port (port deserialization is sensitive to what is the current
862 // workerId).
863 'replyTo': _serializeMessage(replyPort),
864 'functionName': functionName }));
865 }
712 } 866 }
867
868 class Isolate2Impl implements Isolate2 {
869 SendPort sendPort;
870
871 Isolate2Impl(this.sendPort);
872
873 void stop() {}
874 }
875
876 class IsolateFactory implements Isolate2 {
877
878 factory Isolate2.fromCode(Function topLevelFunction) {
879 final name = IsolateNatives._getJSFunctionName(topLevelFunction);
880 if (name == null) {
881 throw new UnsupportedOperationException(
882 "only top-level functions can be spawned.");
883 }
884 return new Isolate2Impl(IsolateNatives._spawn2(name, null, false));
885 }
886
887 factory Isolate2.fromUri(String uri) {
888 return new Isolate2Impl(IsolateNatives._spawn2(null, uri, false));
889 }
890 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698