| Index: sdk/lib/async/zone.dart
|
| diff --git a/sdk/lib/async/zone.dart b/sdk/lib/async/zone.dart
|
| index c2e849eb8618459e1631cc8d91f83ed2e97d93a7..fb3a8fed2742c46b77360a1ac50e659552ae0f11 100644
|
| --- a/sdk/lib/async/zone.dart
|
| +++ b/sdk/lib/async/zone.dart
|
| @@ -62,17 +62,39 @@ abstract class _Zone {
|
| void executeCallback(void fun());
|
|
|
| /**
|
| + * Same as [executeCallback] but catches uncaught errors and gives them to
|
| + * [handleUncaughtError].
|
| + */
|
| + void executeCallbackGuarded(void fun());
|
| +
|
| + /**
|
| * Same as [executeCallback] but does not decrement the number of
|
| * callbacks this zone is waiting for (see [expectCallback]).
|
| */
|
| void executePeriodicCallback(void fun());
|
|
|
| /**
|
| + * Same as [executePeriodicCallback] but catches uncaught errors and gives
|
| + * them to [handleUncaughtError].
|
| + */
|
| + void executeGuardedPeriodicCallback(void fun());
|
| +
|
| + /**
|
| * Runs [fun] asynchronously in this zone.
|
| */
|
| void runAsync(void fun());
|
|
|
| /**
|
| + * Creates a Timer where the callback is executed in this zone.
|
| + */
|
| + Timer createTimer(Duration duration, void callback());
|
| +
|
| + /**
|
| + * Creates a periodic Timer where the callback is executed in this zone.
|
| + */
|
| + Timer createPeriodicTimer(Duration duration, void callback(Timer timer));
|
| +
|
| + /**
|
| * The error zone is the one that is responsible for dealing with uncaught
|
| * errors. Errors are not allowed to cross zones with different error-zones.
|
| */
|
| @@ -173,18 +195,32 @@ class _ZoneBase implements _Zone {
|
| }
|
|
|
| /**
|
| + * Same as [executeCallback] but catches uncaught errors and gives them to
|
| + * [handleUncaughtError].
|
| + */
|
| + void executeCallbackGuarded(void fun()) {
|
| + _openCallbacks--;
|
| + _runGuarded(fun);
|
| + }
|
| +
|
| + /**
|
| * Same as [executeCallback] but doesn't decrement the open-callback counter.
|
| */
|
| void executePeriodicCallback(void fun()) {
|
| _runInZone(fun);
|
| }
|
|
|
| + /**
|
| + * Same as [executePeriodicCallback] but catches uncaught errors and gives
|
| + * them to [handleUncaughtError].
|
| + */
|
| + void executeGuardedPeriodicCallback(void fun()) {
|
| + _runGuarded(fun);
|
| + }
|
| +
|
| _runInZone(fun()) {
|
| if (identical(_Zone._current, this) && _openCallbacks != 0) return fun();
|
| - return _runGuarded(fun);
|
| - }
|
|
|
| - _runGuarded(void fun()) {
|
| _Zone oldZone = _Zone._current;
|
| _Zone._current = this;
|
| // While we are executing the function we don't want to have other
|
| @@ -202,18 +238,35 @@ class _ZoneBase implements _Zone {
|
| }
|
| }
|
|
|
| + /**
|
| + * Runs the function and catches uncaught errors.
|
| + *
|
| + * Uncaught errors are given to [handleUncaughtError].
|
| + */
|
| + _runGuarded(void fun()) {
|
| + try {
|
| + _runInZone(fun);
|
| + } catch(e, s) {
|
| + handleUncaughtError(_asyncError(e, s));
|
| + }
|
| + }
|
| +
|
| runAsync(void fun()) {
|
| _openCallbacks++;
|
| _scheduleAsyncCallback(() {
|
| _openCallbacks--;
|
| - try {
|
| - _runInZone(fun);
|
| - } catch(e, s) {
|
| - handleUncaughtError(_asyncError(e, s));
|
| - }
|
| + _runGuarded(fun);
|
| });
|
| }
|
|
|
| + Timer createTimer(Duration duration, void callback()) {
|
| + return new _ZoneTimer(this, duration, callback);
|
| + }
|
| +
|
| + Timer createPeriodicTimer(Duration duration, void callback(Timer timer)) {
|
| + return new _PeriodicZoneTimer(this, duration, callback);
|
| + }
|
| +
|
| void _addChild(_Zone child) {
|
| _children.add(child);
|
| }
|
| @@ -318,6 +371,62 @@ class _CatchErrorsZone extends _WaitForCompletionZone {
|
| String toString() => "WithErrors ${super.toString()}";
|
| }
|
|
|
| +typedef void _TimerCallback();
|
| +
|
| +/**
|
| + * A [Timer] class that takes zones into account.
|
| + */
|
| +class _ZoneTimer implements Timer {
|
| + final _Zone _zone;
|
| + final _TimerCallback _callback;
|
| + Timer _timer;
|
| + bool _isDone = false;
|
| +
|
| + _ZoneTimer(this._zone, Duration duration, this._callback) {
|
| + _zone.expectCallback();
|
| + _timer = _createTimer(duration, this.run);
|
| + }
|
| +
|
| + void run() {
|
| + _isDone = true;
|
| + _zone.executeCallbackGuarded(_callback);
|
| + }
|
| +
|
| + void cancel() {
|
| + if (!_isDone) _zone.unexpectCallback();
|
| + _isDone = true;
|
| + _timer.cancel();
|
| + }
|
| +}
|
| +
|
| +typedef void _PeriodicTimerCallback(Timer timer);
|
| +
|
| +/**
|
| + * A [Timer] class for periodic callbacks that takes zones into account.
|
| + */
|
| +class _PeriodicZoneTimer implements Timer {
|
| + final _Zone _zone;
|
| + final _PeriodicTimerCallback _callback;
|
| + Timer _timer;
|
| + bool _isDone = false;
|
| +
|
| + _PeriodicZoneTimer(this._zone, Duration duration, this._callback) {
|
| + _zone.expectCallback();
|
| + _timer = _createPeriodicTimer(duration, this.run);
|
| + }
|
| +
|
| + void run(Timer timer) {
|
| + assert(identical(_timer, timer));
|
| + _zone.executeGuardedPeriodicCallback(() { _callback(this); });
|
| + }
|
| +
|
| + void cancel() {
|
| + if (!_isDone) _zone.unexpectCallback();
|
| + _isDone = true;
|
| + _timer.cancel();
|
| + }
|
| +}
|
| +
|
| Stream catchErrors(void body()) {
|
| _CatchErrorsZone catchErrorsZone = new _CatchErrorsZone(_Zone._current);
|
| catchErrorsZone.runWaitForCompletion(body);
|
|
|