OLD | NEW |
---|---|
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 schedule; | 5 library schedule; |
6 | 6 |
7 import 'dart:async'; | 7 import 'dart:async'; |
8 import 'dart:collection'; | 8 import 'dart:collection'; |
9 | 9 |
10 import 'package:stack_trace/stack_trace.dart'; | 10 import 'package:stack_trace/stack_trace.dart'; |
(...skipping 361 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
372 | 372 |
373 /// The toal number of out-of-band callbacks that have been registered on | 373 /// The toal number of out-of-band callbacks that have been registered on |
374 /// [this]. | 374 /// [this]. |
375 int _totalCallbacks = 0; | 375 int _totalCallbacks = 0; |
376 | 376 |
377 /// Whether to stop running after the current task. | 377 /// Whether to stop running after the current task. |
378 bool _aborted = false; | 378 bool _aborted = false; |
379 | 379 |
380 /// The descriptions of all callbacks that are blocking the completion of | 380 /// The descriptions of all callbacks that are blocking the completion of |
381 /// [this]. | 381 /// [this]. |
382 List<String> get pendingCallbacks => | 382 List<PendingCallback> get pendingCallbacks => |
383 new UnmodifiableListView<String>(_pendingCallbacks); | 383 new UnmodifiableListView<PendingCallback>(_pendingCallbacks); |
384 final _pendingCallbacks = new Queue<String>(); | 384 final _pendingCallbacks = new Queue<PendingCallback>(); |
385 | 385 |
386 /// A completer that will be completed once [_pendingCallbacks] becomes empty | 386 /// A completer that will be completed once [_pendingCallbacks] becomes empty |
387 /// after the queue finishes running its tasks. | 387 /// after the queue finishes running its tasks. |
388 Future get _noPendingCallbacks => _noPendingCallbacksCompleter.future; | 388 Future get _noPendingCallbacks => _noPendingCallbacksCompleter.future; |
389 final Completer _noPendingCallbacksCompleter = new Completer(); | 389 final Completer _noPendingCallbacksCompleter = new Completer(); |
390 | 390 |
391 /// A [Future] that completes when the tasks in [this] are all complete. If an | 391 /// A [Future] that completes when the tasks in [this] are all complete. If an |
392 /// error occurs while running this queue, the returned [Future] will complete | 392 /// error occurs while running this queue, the returned [Future] will complete |
393 /// with that error. | 393 /// with that error. |
394 /// | 394 /// |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
498 /// chain. This will also block [this] from completing until the returned | 498 /// chain. This will also block [this] from completing until the returned |
499 /// function has been called. It's used to ensure that out-of-band callbacks | 499 /// function has been called. It's used to ensure that out-of-band callbacks |
500 /// are properly handled by the scheduled test. | 500 /// are properly handled by the scheduled test. |
501 Function _wrapAsync(fn(arg), String description) { | 501 Function _wrapAsync(fn(arg), String description) { |
502 assert(_schedule.state == ScheduleState.SET_UP || isRunning); | 502 assert(_schedule.state == ScheduleState.SET_UP || isRunning); |
503 | 503 |
504 // It's possible that the queue timed out before [fn] finished. | 504 // It's possible that the queue timed out before [fn] finished. |
505 bool _timedOut() => | 505 bool _timedOut() => |
506 _schedule.currentQueue != this || pendingCallbacks.isEmpty; | 506 _schedule.currentQueue != this || pendingCallbacks.isEmpty; |
507 | 507 |
508 if (description == null) { | 508 _totalCallbacks++; |
509 description = "Out-of-band operation #${_totalCallbacks}"; | 509 var trace = captureStackTraces ? new Trace.current() : null; |
510 } | 510 var pendingCallback = new PendingCallback._(() { |
511 var fullDescription = description; | |
512 if (fullDescription == null) { | |
513 fullDescription = "Out-of-band operation #${_totalCallbacks}"; | |
514 } | |
511 | 515 |
512 if (captureStackTraces) { | 516 if (captureStackTraces) { |
Bob Nystrom
2013/04/30 23:05:36
If capturing stack traces is fast enough now, how
nweiz
2013/04/30 23:13:14
Done.
| |
513 var stackString = prefixLines(terseTraceString(new Trace.current())); | 517 var stackString = prefixLines(terseTraceString(trace)); |
514 description += "\n\nStack trace:\n$stackString"; | 518 fullDescription += "\n\nStack trace:\n$stackString"; |
515 } | 519 } |
520 }); | |
521 _pendingCallbacks.add(pendingCallback); | |
516 | 522 |
517 _totalCallbacks++; | |
518 | |
519 _pendingCallbacks.add(description); | |
520 return (arg) { | 523 return (arg) { |
521 try { | 524 try { |
522 return fn(arg); | 525 return fn(arg); |
523 } catch (e, stackTrace) { | 526 } catch (e, stackTrace) { |
524 var error = new ScheduleError.from( | 527 var error = new ScheduleError.from( |
525 _schedule, e, stackTrace: stackTrace); | 528 _schedule, e, stackTrace: stackTrace); |
526 if (_timedOut()) { | 529 if (_timedOut()) { |
527 _schedule._signalPostTimeoutError(error); | 530 _schedule._signalPostTimeoutError(error); |
528 } else { | 531 } else { |
529 _schedule.signalError(error); | 532 _schedule.signalError(error); |
530 } | 533 } |
531 } finally { | 534 } finally { |
532 if (_timedOut()) return; | 535 if (_timedOut()) return; |
533 | 536 |
534 _pendingCallbacks.remove(description); | 537 _pendingCallbacks.remove(pendingCallback); |
535 if (_pendingCallbacks.isEmpty && !isRunningTasks) { | 538 if (_pendingCallbacks.isEmpty && !isRunningTasks) { |
536 _noPendingCallbacksCompleter.complete(); | 539 _noPendingCallbacksCompleter.complete(); |
537 } | 540 } |
538 } | 541 } |
539 }; | 542 }; |
540 } | 543 } |
541 | 544 |
542 /// Signals that an out-of-band error has been detected and the queue should | 545 /// Signals that an out-of-band error has been detected and the queue should |
543 /// stop running as soon as possible. | 546 /// stop running as soon as possible. |
544 void _signalError(ScheduleError error) { | 547 void _signalError(ScheduleError error) { |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
598 return prefixLines(childString, | 601 return prefixLines(childString, |
599 firstPrefix: " $prefix ", prefix: " | "); | 602 firstPrefix: " $prefix ", prefix: " | "); |
600 }).join('\n'); | 603 }).join('\n'); |
601 taskString = '$taskString\n$childrenString'; | 604 taskString = '$taskString\n$childrenString'; |
602 } | 605 } |
603 | 606 |
604 return taskString; | 607 return taskString; |
605 }).join("\n"); | 608 }).join("\n"); |
606 } | 609 } |
607 } | 610 } |
611 | |
612 /// A thunk for lazily resolving the description of a [PendingCallback]. | |
613 typedef String _DescriptionThunk(); | |
Bob Nystrom
2013/04/30 23:05:36
Oh Dart and your awful function type syntax. You c
nweiz
2013/04/30 23:13:14
Currently we're using this once each in several di
| |
614 | |
615 /// An identifier for an out-of-band callback running during a schedule. | |
616 class PendingCallback { | |
Bob Nystrom
2013/04/30 23:05:36
The fact that it's for an out-of-band callback isn
nweiz
2013/04/30 23:13:14
I'm more interested in being able to add more pend
Bob Nystrom
2013/05/01 00:02:25
In that case, keep the name of this type, but upda
nweiz
2013/05/01 00:33:44
That's specifically referring to the string, not t
| |
617 final _DescriptionThunk _thunk; | |
618 String _description; | |
619 | |
620 /// The string description of the callback. | |
621 String get description { | |
622 if (_description == null) _description = _thunk(); | |
623 return _description; | |
624 } | |
625 | |
626 String toString() => description; | |
627 | |
628 PendingCallback._(this._thunk); | |
629 } | |
OLD | NEW |