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 |