| OLD | NEW |
| 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 /** Implementation of [Isolate2]. */ | |
| 6 class _Isolate2Impl implements Isolate2 { | |
| 7 SendPort sendPort; | |
| 8 | |
| 9 _Isolate2Impl(this.sendPort); | |
| 10 } | |
| 11 | |
| 12 /** | 5 /** |
| 13 * 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 |
| 14 * 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). |
| 15 * | 8 * |
| 16 * 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 |
| 17 * implement the semantics of isolates in JavaScript. Without this we would have | 10 * implement the semantics of isolates in JavaScript. Without this we would have |
| 18 * been forced to implement more code (including the top-level event loop) in | 11 * been forced to implement more code (including the top-level event loop) in |
| 19 * JavaScript itself. | 12 * JavaScript itself. |
| 20 */ | 13 */ |
| 21 GlobalState get globalState() native "return \$globalState;"; | 14 GlobalState get globalState() native "return \$globalState;"; |
| (...skipping 371 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 393 */ | 386 */ |
| 394 static _getEventData(e) native "return e.data"; | 387 static _getEventData(e) native "return e.data"; |
| 395 | 388 |
| 396 /** | 389 /** |
| 397 * Process messages on a worker, either to control the worker instance or to | 390 * Process messages on a worker, either to control the worker instance or to |
| 398 * pass messages along to the isolate running in the worker. | 391 * pass messages along to the isolate running in the worker. |
| 399 */ | 392 */ |
| 400 static void _processWorkerMessage(sender, e) { | 393 static void _processWorkerMessage(sender, e) { |
| 401 var msg = _deserializeMessage(_getEventData(e)); | 394 var msg = _deserializeMessage(_getEventData(e)); |
| 402 switch (msg['command']) { | 395 switch (msg['command']) { |
| 403 // TODO(sigmund): delete after we migrate to Isolate2 | 396 // TODO(sigmund): delete after we migrate to the new API |
| 404 case 'start': | 397 case 'start': |
| 405 globalState.currentWorkerId = msg['id']; | 398 globalState.currentWorkerId = msg['id']; |
| 406 var runnerObject = | 399 var runnerObject = |
| 407 _allocate(_getJSConstructorFromName(msg['factoryName'])); | 400 _allocate(_getJSConstructorFromName(msg['factoryName'])); |
| 408 var serializedReplyTo = msg['replyTo']; | 401 var serializedReplyTo = msg['replyTo']; |
| 409 globalState.topEventLoop.enqueue(new IsolateContext(), function() { | 402 globalState.topEventLoop.enqueue(new IsolateContext(), function() { |
| 410 var replyTo = _deserializeMessage(serializedReplyTo); | 403 var replyTo = _deserializeMessage(serializedReplyTo); |
| 411 _startIsolate(runnerObject, replyTo); | 404 _startIsolate(runnerObject, replyTo); |
| 412 }, 'worker-start'); | 405 }, 'worker-start'); |
| 413 globalState.topEventLoop.run(); | 406 globalState.topEventLoop.run(); |
| 414 break; | 407 break; |
| 415 case 'start2': | 408 case 'start2': |
| 416 globalState.currentWorkerId = msg['id']; | 409 globalState.currentWorkerId = msg['id']; |
| 417 Function entryPoint = _getJSFunctionFromName(msg['functionName']); | 410 Function entryPoint = _getJSFunctionFromName(msg['functionName']); |
| 418 var replyTo = _deserializeMessage(msg['replyTo']); | 411 var replyTo = _deserializeMessage(msg['replyTo']); |
| 419 globalState.topEventLoop.enqueue(new IsolateContext(), function() { | 412 globalState.topEventLoop.enqueue(new IsolateContext(), function() { |
| 420 _startIsolate2(entryPoint, replyTo); | 413 _startIsolate2(entryPoint, replyTo); |
| 421 }, 'worker-start'); | 414 }, 'worker-start'); |
| 422 globalState.topEventLoop.run(); | 415 globalState.topEventLoop.run(); |
| 423 break; | 416 break; |
| 424 // TODO(sigmund): delete after we migrate to Isolate2 | 417 // TODO(sigmund): delete after we migrate to the new API |
| 425 case 'spawn-worker': | 418 case 'spawn-worker': |
| 426 _spawnWorker(msg['factoryName'], msg['replyPort']); | 419 _spawnWorker(msg['factoryName'], msg['replyPort']); |
| 427 break; | 420 break; |
| 428 case 'spawn-worker2': | 421 case 'spawn-worker2': |
| 429 _spawnWorker2(msg['functionName'], msg['uri'], msg['replyPort']); | 422 _spawnWorker2(msg['functionName'], msg['uri'], msg['replyPort']); |
| 430 break; | 423 break; |
| 431 case 'message': | 424 case 'message': |
| 432 msg['port'].send(msg['msg'], msg['replyTo']); | 425 msg['port'].send(msg['msg'], msg['replyTo']); |
| 433 globalState.topEventLoop.run(); | 426 globalState.topEventLoop.run(); |
| 434 break; | 427 break; |
| (...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 580 'replyPort': replyPort})); | 573 'replyPort': replyPort})); |
| 581 } else { | 574 } else { |
| 582 _spawnWorker2(functionName, uri, replyPort); | 575 _spawnWorker2(functionName, uri, replyPort); |
| 583 } | 576 } |
| 584 } | 577 } |
| 585 | 578 |
| 586 static SendPort _startNonWorker2( | 579 static SendPort _startNonWorker2( |
| 587 String functionName, String uri, SendPort replyPort) { | 580 String functionName, String uri, SendPort replyPort) { |
| 588 // TODO(eub): support IE9 using an iframe -- Dart issue 1702. | 581 // TODO(eub): support IE9 using an iframe -- Dart issue 1702. |
| 589 if (uri != null) throw new UnsupportedOperationException( | 582 if (uri != null) throw new UnsupportedOperationException( |
| 590 "Currently Isolate2.fromUri is not supported without web workers."); | 583 "Currently spawnUri is not supported without web workers."); |
| 591 globalState.topEventLoop.enqueue(new IsolateContext(), function() { | 584 globalState.topEventLoop.enqueue(new IsolateContext(), function() { |
| 592 final func = _getJSFunctionFromName(functionName); | 585 final func = _getJSFunctionFromName(functionName); |
| 593 _startIsolate2(func, replyPort); | 586 _startIsolate2(func, replyPort); |
| 594 }, 'nonworker start'); | 587 }, 'nonworker start'); |
| 595 } | 588 } |
| 596 | 589 |
| 597 static void _startIsolate2(Function topLevel, SendPort replyTo) { | 590 static void _startIsolate2(Function topLevel, SendPort replyTo) { |
| 598 fillStatics(globalState.currentContext); | 591 fillStatics(globalState.currentContext); |
| 599 final port = new ReceivePort(); | 592 _port = new ReceivePort(); |
| 600 replyTo.send(_SPAWNED_SIGNAL, port.toSendPort()); | 593 replyTo.send(_SPAWNED_SIGNAL, port.toSendPort()); |
| 601 topLevel(port); | 594 topLevel(); |
| 602 } | 595 } |
| 603 | 596 |
| 604 /** | 597 /** |
| 605 * Spawns an isolate in a worker. [factoryName] is the Javascript constructor | 598 * Spawns an isolate in a worker. [factoryName] is the Javascript constructor |
| 606 * name for the isolate entry point class. | 599 * name for the isolate entry point class. |
| 607 */ | 600 */ |
| 608 static void _spawnWorker2(functionName, uri, replyPort) { | 601 static void _spawnWorker2(functionName, uri, replyPort) { |
| 609 // TODO(eub): convert to 'main' once we switch back to port at top-level. | 602 if (functionName == null) functionName = 'main'; |
| 610 if (functionName == null) functionName = 'isolateMain'; | |
| 611 if (uri == null) uri = _thisScript; | 603 if (uri == null) uri = _thisScript; |
| 612 if (!(new Uri.fromString(uri).isAbsolute())) { | 604 if (!(new Uri.fromString(uri).isAbsolute())) { |
| 613 // The constructor of dom workers requires an absolute URL. If we use a | 605 // The constructor of dom workers requires an absolute URL. If we use a |
| 614 // relative path we will get a DOM exception. | 606 // relative path we will get a DOM exception. |
| 615 String prefix = _thisScript.substring(0, _thisScript.lastIndexOf('/')); | 607 String prefix = _thisScript.substring(0, _thisScript.lastIndexOf('/')); |
| 616 uri = "$prefix/$uri"; | 608 uri = "$prefix/$uri"; |
| 617 } | 609 } |
| 618 final worker = _newWorker(uri); | 610 final worker = _newWorker(uri); |
| 619 worker.onmessage = (e) { _processWorkerMessage(worker, e); }; | 611 worker.onmessage = (e) { _processWorkerMessage(worker, e); }; |
| 620 var workerId = globalState.nextWorkerId++; | 612 var workerId = globalState.nextWorkerId++; |
| 621 // We also store the id on the worker itself so that we can unregister it. | 613 // We also store the id on the worker itself so that we can unregister it. |
| 622 worker.id = workerId; | 614 worker.id = workerId; |
| 623 globalState.workers[workerId] = worker; | 615 globalState.workers[workerId] = worker; |
| 624 worker.postMessage(_serializeMessage({ | 616 worker.postMessage(_serializeMessage({ |
| 625 'command': 'start2', | 617 'command': 'start2', |
| 626 'id': workerId, | 618 'id': workerId, |
| 627 // Note: we serialize replyPort twice because the child worker needs to | 619 // Note: we serialize replyPort twice because the child worker needs to |
| 628 // first deserialize the worker id, before it can correctly deserialize | 620 // first deserialize the worker id, before it can correctly deserialize |
| 629 // the port (port deserialization is sensitive to what is the current | 621 // the port (port deserialization is sensitive to what is the current |
| 630 // workerId). | 622 // workerId). |
| 631 'replyTo': _serializeMessage(replyPort), | 623 'replyTo': _serializeMessage(replyPort), |
| 632 'functionName': functionName })); | 624 'functionName': functionName })); |
| 633 } | 625 } |
| 634 } | 626 } |
| OLD | NEW |