Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(291)

Unified Diff: sdk/lib/async/zone.dart

Issue 15764003: Add Zone support for Timers. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Reupload Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « sdk/lib/async/timer.dart ('k') | tests/lib/async/catch_errors10_test.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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);
« no previous file with comments | « sdk/lib/async/timer.dart ('k') | tests/lib/async/catch_errors10_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698