| 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 library _isolate_helper; | 5 library _isolate_helper; |
| 6 | 6 |
| 7 import 'dart:_js_embedded_names' show | 7 import 'dart:_js_embedded_names' show |
| 8 CLASS_ID_EXTRACTOR, | 8 CLASS_ID_EXTRACTOR, |
| 9 CLASS_FIELDS_EXTRACTOR, | 9 CLASS_FIELDS_EXTRACTOR, |
| 10 CREATE_NEW_ISOLATE, | 10 CREATE_NEW_ISOLATE, |
| (...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 304 /// receive ports and no scheduled timers, because it hasn't had time to | 304 /// receive ports and no scheduled timers, because it hasn't had time to |
| 305 /// create them yet. | 305 /// create them yet. |
| 306 bool initialized = false; | 306 bool initialized = false; |
| 307 | 307 |
| 308 // TODO(lrn): Store these in single "PauseState" object, so they don't take | 308 // TODO(lrn): Store these in single "PauseState" object, so they don't take |
| 309 // up as much room when not pausing. | 309 // up as much room when not pausing. |
| 310 bool isPaused = false; | 310 bool isPaused = false; |
| 311 List<_IsolateEvent> delayedEvents = []; | 311 List<_IsolateEvent> delayedEvents = []; |
| 312 Set<Capability> pauseTokens = new Set(); | 312 Set<Capability> pauseTokens = new Set(); |
| 313 | 313 |
| 314 // Container with the "on exit" handler send-ports. | 314 // Container with the "on exit" handler send-ports and responses. |
| 315 var doneHandlers; | 315 var doneHandlers; |
| 316 | 316 |
| 317 /** | 317 /** |
| 318 * Queue of functions to call when the current event is complete. | 318 * Queue of functions to call when the current event is complete. |
| 319 * | 319 * |
| 320 * These events are not just put at the front of the event queue, because | 320 * These events are not just put at the front of the event queue, because |
| 321 * they represent control messages, and should be handled even if the | 321 * they represent control messages, and should be handled even if the |
| 322 * event queue is paused. | 322 * event queue is paused. |
| 323 */ | 323 */ |
| 324 var _scheduledControlEvents; | 324 var _scheduledControlEvents; |
| (...skipping 23 matching lines...) Expand all Loading... |
| 348 if (pauseTokens.isEmpty) { | 348 if (pauseTokens.isEmpty) { |
| 349 while(delayedEvents.isNotEmpty) { | 349 while(delayedEvents.isNotEmpty) { |
| 350 _IsolateEvent event = delayedEvents.removeLast(); | 350 _IsolateEvent event = delayedEvents.removeLast(); |
| 351 _globalState.topEventLoop.prequeue(event); | 351 _globalState.topEventLoop.prequeue(event); |
| 352 } | 352 } |
| 353 isPaused = false; | 353 isPaused = false; |
| 354 } | 354 } |
| 355 _updateGlobalState(); | 355 _updateGlobalState(); |
| 356 } | 356 } |
| 357 | 357 |
| 358 void addDoneListener(SendPort responsePort) { | 358 void addDoneListener(SendPort responsePort, Object response) { |
| 359 if (doneHandlers == null) { | 359 if (doneHandlers == null) { |
| 360 doneHandlers = []; | 360 // TODO(lrn): Use map optimized for few keys. |
| 361 doneHandlers = new HashMap(); |
| 361 } | 362 } |
| 362 // If necessary, we can switch doneHandlers to a Set if it gets larger. | 363 doneHandlers[responsePort] = response; |
| 363 // That is not expected to happen in practice. | |
| 364 if (doneHandlers.contains(responsePort)) return; | |
| 365 doneHandlers.add(responsePort); | |
| 366 } | 364 } |
| 367 | 365 |
| 368 void removeDoneListener(SendPort responsePort) { | 366 void removeDoneListener(SendPort responsePort) { |
| 369 if (doneHandlers == null) return; | 367 if (doneHandlers == null) return; |
| 370 doneHandlers.remove(responsePort); | 368 doneHandlers.remove(responsePort); |
| 371 } | 369 } |
| 372 | 370 |
| 373 void setErrorsFatal(Capability authentification, bool errorsAreFatal) { | 371 void setErrorsFatal(Capability authentification, bool errorsAreFatal) { |
| 374 if (terminateCapability != authentification) return; | 372 if (terminateCapability != authentification) return; |
| 375 this.errorsAreFatal = errorsAreFatal; | 373 this.errorsAreFatal = errorsAreFatal; |
| 376 } | 374 } |
| 377 | 375 |
| 378 void handlePing(SendPort responsePort, int pingType) { | 376 void handlePing(SendPort responsePort, int pingType, Object response) { |
| 379 if (pingType == Isolate.IMMEDIATE || | 377 if (pingType == Isolate.IMMEDIATE || |
| 380 (pingType == Isolate.BEFORE_NEXT_EVENT && | 378 (pingType == Isolate.BEFORE_NEXT_EVENT && |
| 381 !_isExecutingEvent)) { | 379 !_isExecutingEvent)) { |
| 382 responsePort.send(null); | 380 responsePort.send(response); |
| 383 return; | 381 return; |
| 384 } | 382 } |
| 385 void respond() { responsePort.send(null); } | 383 void respond() { responsePort.send(response); } |
| 386 if (pingType == Isolate.AS_EVENT) { | |
| 387 _globalState.topEventLoop.enqueue(this, respond, "ping"); | |
| 388 return; | |
| 389 } | |
| 390 assert(pingType == Isolate.BEFORE_NEXT_EVENT); | 384 assert(pingType == Isolate.BEFORE_NEXT_EVENT); |
| 391 if (_scheduledControlEvents == null) { | 385 if (_scheduledControlEvents == null) { |
| 392 _scheduledControlEvents = new Queue(); | 386 _scheduledControlEvents = new Queue(); |
| 393 } | 387 } |
| 394 _scheduledControlEvents.addLast(respond); | 388 _scheduledControlEvents.addLast(respond); |
| 395 } | 389 } |
| 396 | 390 |
| 397 void handleKill(Capability authentification, int priority) { | 391 void handleKill(Capability authentification, int priority) { |
| 398 if (this.terminateCapability != authentification) return; | 392 if (this.terminateCapability != authentification) return; |
| 399 if (priority == Isolate.IMMEDIATE || | 393 if (priority == Isolate.IMMEDIATE || |
| 400 (priority == Isolate.BEFORE_NEXT_EVENT && | 394 (priority == Isolate.BEFORE_NEXT_EVENT && |
| 401 !_isExecutingEvent)) { | 395 !_isExecutingEvent)) { |
| 402 kill(); | 396 kill(); |
| 403 return; | 397 return; |
| 404 } | 398 } |
| 405 if (priority == Isolate.AS_EVENT) { | |
| 406 _globalState.topEventLoop.enqueue(this, kill, "kill"); | |
| 407 return; | |
| 408 } | |
| 409 assert(priority == Isolate.BEFORE_NEXT_EVENT); | 399 assert(priority == Isolate.BEFORE_NEXT_EVENT); |
| 410 if (_scheduledControlEvents == null) { | 400 if (_scheduledControlEvents == null) { |
| 411 _scheduledControlEvents = new Queue(); | 401 _scheduledControlEvents = new Queue(); |
| 412 } | 402 } |
| 413 _scheduledControlEvents.addLast(kill); | 403 _scheduledControlEvents.addLast(kill); |
| 414 } | 404 } |
| 415 | 405 |
| 416 void addErrorListener(SendPort port) { | 406 void addErrorListener(SendPort port) { |
| 417 errorPorts.add(port); | 407 errorPorts.add(port); |
| 418 } | 408 } |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 492 */ | 482 */ |
| 493 void handleControlMessage(message) { | 483 void handleControlMessage(message) { |
| 494 switch (message[0]) { | 484 switch (message[0]) { |
| 495 case "pause": | 485 case "pause": |
| 496 addPause(message[1], message[2]); | 486 addPause(message[1], message[2]); |
| 497 break; | 487 break; |
| 498 case "resume": | 488 case "resume": |
| 499 removePause(message[1]); | 489 removePause(message[1]); |
| 500 break; | 490 break; |
| 501 case 'add-ondone': | 491 case 'add-ondone': |
| 502 addDoneListener(message[1]); | 492 addDoneListener(message[1], message[2]); |
| 503 break; | 493 break; |
| 504 case 'remove-ondone': | 494 case 'remove-ondone': |
| 505 removeDoneListener(message[1]); | 495 removeDoneListener(message[1]); |
| 506 break; | 496 break; |
| 507 case 'set-errors-fatal': | 497 case 'set-errors-fatal': |
| 508 setErrorsFatal(message[1], message[2]); | 498 setErrorsFatal(message[1], message[2]); |
| 509 break; | 499 break; |
| 510 case "ping": | 500 case "ping": |
| 511 handlePing(message[1], message[2]); | 501 handlePing(message[1], message[2], message[3]); |
| 512 break; | 502 break; |
| 513 case "kill": | 503 case "kill": |
| 514 handleKill(message[1], message[2]); | 504 handleKill(message[1], message[2]); |
| 515 break; | 505 break; |
| 516 case "getErrors": | 506 case "getErrors": |
| 517 addErrorListener(message[1]); | 507 addErrorListener(message[1]); |
| 518 break; | 508 break; |
| 519 case "stopErrors": | 509 case "stopErrors": |
| 520 removeErrorListener(message[1]); | 510 removeErrorListener(message[1]); |
| 521 break; | 511 break; |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 567 // we are listening on ourselves. | 557 // we are listening on ourselves. |
| 568 // Closes all ports, including control port. | 558 // Closes all ports, including control port. |
| 569 for (var port in ports.values) { | 559 for (var port in ports.values) { |
| 570 port._close(); | 560 port._close(); |
| 571 } | 561 } |
| 572 ports.clear(); | 562 ports.clear(); |
| 573 weakPorts.clear(); | 563 weakPorts.clear(); |
| 574 _globalState.isolates.remove(id); // indicate this isolate is not active | 564 _globalState.isolates.remove(id); // indicate this isolate is not active |
| 575 errorPorts.clear(); | 565 errorPorts.clear(); |
| 576 if (doneHandlers != null) { | 566 if (doneHandlers != null) { |
| 577 for (SendPort port in doneHandlers) { | 567 doneHandlers.forEach((port, response) { port.send(response); }); |
| 578 port.send(null); | |
| 579 } | |
| 580 doneHandlers = null; | 568 doneHandlers = null; |
| 581 } | 569 } |
| 582 } | 570 } |
| 583 | 571 |
| 584 /** Unregister a port on this isolate. */ | 572 /** Unregister a port on this isolate. */ |
| 585 void unregister(int portId) { | 573 void unregister(int portId) { |
| 586 ports.remove(portId); | 574 ports.remove(portId); |
| 587 weakPorts.remove(portId); | 575 weakPorts.remove(portId); |
| 588 _updateGlobalState(); | 576 _updateGlobalState(); |
| 589 } | 577 } |
| (...skipping 858 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1448 } | 1436 } |
| 1449 | 1437 |
| 1450 bool operator==(Object other) { | 1438 bool operator==(Object other) { |
| 1451 if (identical(other, this)) return true; | 1439 if (identical(other, this)) return true; |
| 1452 if (other is CapabilityImpl) { | 1440 if (other is CapabilityImpl) { |
| 1453 return identical(_id, other._id); | 1441 return identical(_id, other._id); |
| 1454 } | 1442 } |
| 1455 return false; | 1443 return false; |
| 1456 } | 1444 } |
| 1457 } | 1445 } |
| OLD | NEW |