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

Side by Side Diff: sdk/lib/async/zone.dart

Issue 16801008: catchErrors and waitForCompletion now based on runZonedExperimental. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Some tests. 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | tests/lib/async/catch_errors.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 part of dart.async; 5 part of dart.async;
6 6
7 /** 7 /**
8 * A Zone represents the asynchronous version of a dynamic extent. Asynchronous 8 * A Zone represents the asynchronous version of a dynamic extent. Asynchronous
9 * callbacks are executed in the zone they have been queued in. For example, 9 * callbacks are executed in the zone they have been queued in. For example,
10 * the callback of a `future.then` is executed in the same zone as the one where 10 * the callback of a `future.then` is executed in the same zone as the one where
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after
230 230
231 _Zone oldZone = _Zone._current; 231 _Zone oldZone = _Zone._current;
232 _Zone._current = this; 232 _Zone._current = this;
233 // While we are executing the function we don't want to have other 233 // While we are executing the function we don't want to have other
234 // synchronous calls to think that they closed the zone. By incrementing 234 // synchronous calls to think that they closed the zone. By incrementing
235 // the _openCallbacks count we make sure that their test will fail. 235 // the _openCallbacks count we make sure that their test will fail.
236 // As a side effect it will make nested calls faster since they are 236 // As a side effect it will make nested calls faster since they are
237 // (probably) in the same zone and have an _openCallbacks > 0. 237 // (probably) in the same zone and have an _openCallbacks > 0.
238 bool oldIsExecuting = _isExecutingCallback; 238 bool oldIsExecuting = _isExecutingCallback;
239 _isExecutingCallback = true; 239 _isExecutingCallback = true;
240 // TODO(11244): remove second try when VM bug is fixed.
Lasse Reichstein Nielsen 2013/06/13 12:10:08 Bug has been marked as duplicate of 430, so renumb
floitsch 2013/06/13 14:38:55 Done.
240 try { 241 try {
241 return fun(); 242 try {
242 } catch(e, s) { 243 return fun();
243 if (handleUncaught) { 244 } catch(e, s) {
244 handleUncaughtError(_asyncError(e, s)); 245 if (handleUncaught) {
245 } else { 246 handleUncaughtError(_asyncError(e, s));
246 rethrow; 247 } else {
248 rethrow;
249 }
247 } 250 }
248 } finally { 251 } finally {
249 _isExecutingCallback = oldIsExecuting; 252 _isExecutingCallback = oldIsExecuting;
250 _Zone._current = oldZone; 253 _Zone._current = oldZone;
251 _checkIfDone(); 254 _checkIfDone();
252 } 255 }
253 } 256 }
254 257
255 /** 258 /**
256 * Runs the function and catches uncaught errors. 259 * Runs the function and catches uncaught errors.
257 * 260 *
258 * Uncaught errors are given to [handleUncaughtError]. 261 * Uncaught errors are given to [handleUncaughtError].
259 */ 262 */
260 _runGuarded(void fun()) { 263 _runGuarded(void fun()) {
261 _runInZone(fun, true); 264 return _runInZone(fun, true);
262 } 265 }
263 266
264 /** 267 /**
265 * Runs the function but doesn't catch uncaught errors. 268 * Runs the function but doesn't catch uncaught errors.
266 */ 269 */
267 _runUnguarded(void fun()) { 270 _runUnguarded(void fun()) {
268 _runInZone(fun, false); 271 return _runInZone(fun, false);
269 } 272 }
270 273
271 runAsync(void fun()) { 274 runAsync(void fun()) {
272 _openCallbacks++; 275 _openCallbacks++;
273 _scheduleAsyncCallback(() { 276 _scheduleAsyncCallback(() {
274 _openCallbacks--; 277 _openCallbacks--;
275 _runGuarded(fun); 278 _runGuarded(fun);
276 }); 279 });
277 } 280 }
278 281
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
338 */ 341 */
339 class _WaitForCompletionZone extends _ZoneBase { 342 class _WaitForCompletionZone extends _ZoneBase {
340 final _CompletionCallback _onDone; 343 final _CompletionCallback _onDone;
341 344
342 _WaitForCompletionZone(_Zone parentZone, this._onDone) : super(parentZone); 345 _WaitForCompletionZone(_Zone parentZone, this._onDone) : super(parentZone);
343 346
344 /** 347 /**
345 * Runs the given function asynchronously. Executes the [_onDone] callback 348 * Runs the given function asynchronously. Executes the [_onDone] callback
346 * when the zone is done. 349 * when the zone is done.
347 */ 350 */
348 void runWaitForCompletion(void fun()) { 351 runWaitForCompletion(void fun()) {
349 this._runGuarded(fun); 352 return this._runUnguarded(fun);
350 } 353 }
351 354
352 _dispose() { 355 _dispose() {
353 super._dispose(); 356 super._dispose();
354 _onDone(); 357 _onDone();
355 } 358 }
356 359
357 String toString() => "WaitForCompletion ${super.toString()}"; 360 String toString() => "WaitForCompletion ${super.toString()}";
358 } 361 }
359 362
360 typedef bool _HandleErrorCallback(error); 363 typedef bool _HandleErrorCallback(error);
361 364
362 /** 365 /**
363 * A zone that collects all uncaught errors and provides them in a stream. 366 * A zone that collects all uncaught errors and provides them in a stream.
364 * The stream is closed when the zone is done. 367 * The stream is closed when the zone is done.
365 */ 368 */
366 class _CatchErrorsZone extends _WaitForCompletionZone { 369 class _CatchErrorsZone extends _WaitForCompletionZone {
367 final _HandleErrorCallback _handleError; 370 final _HandleErrorCallback _handleError;
368 371
369 _CatchErrorsZone(_Zone parentZone, this._handleError, void onDone()) 372 _CatchErrorsZone(_Zone parentZone, this._handleError, void onDone())
370 : super(parentZone, onDone); 373 : super(parentZone, onDone);
371 374
372 _Zone get _errorZone => this; 375 _Zone get _errorZone => this;
373 376
374 handleUncaughtError(error) { 377 handleUncaughtError(error) {
375 if (!_handleError(error)) _parentZone.handleUncaughtError(error); 378 if (!_handleError(error)) _parentZone.handleUncaughtError(error);
376 } 379 }
377 380
381 /**
382 * Runs the given function asynchronously. Executes the [_onDone] callback
383 * when the zone is done.
384 */
385 runWaitForCompletion(void fun()) {
386 return this._runGuarded(fun);
387 }
388
378 String toString() => "WithErrors ${super.toString()}"; 389 String toString() => "WithErrors ${super.toString()}";
379 } 390 }
380 391
381 typedef void _TimerCallback(); 392 typedef void _TimerCallback();
382 393
383 /** 394 /**
384 * A [Timer] class that takes zones into account. 395 * A [Timer] class that takes zones into account.
385 */ 396 */
386 class _ZoneTimer implements Timer { 397 class _ZoneTimer implements Timer {
387 final _Zone _zone; 398 final _Zone _zone;
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
427 _zone.executePeriodicCallbackGuarded(() { _callback(this); }); 438 _zone.executePeriodicCallbackGuarded(() { _callback(this); });
428 } 439 }
429 440
430 void cancel() { 441 void cancel() {
431 if (!_isDone) _zone.cancelCallbackExpectation(); 442 if (!_isDone) _zone.cancelCallbackExpectation();
432 _isDone = true; 443 _isDone = true;
433 _timer.cancel(); 444 _timer.cancel();
434 } 445 }
435 } 446 }
436 447
437 Stream catchErrors(void body()) { 448 runZonedExperimental(body(), { bool onError(error), void onDone() }) {
Lasse Reichstein Nielsen 2013/06/13 12:10:08 I assume the name is experimental too :)
floitsch 2013/06/13 14:38:55 I would keep the name. Until we feel comfortable t
438 _CatchErrorsZone catchErrorsZone; 449 // TODO(floitsch): we probably still want to install a new Zone.
439 StreamController controller; 450 if (onError == null && onDone == null) return body();
440 451 if (onError == null) {
441 void onListen() { 452 _Zone zone = new _WaitForCompletionZone(_Zone._current, onDone);
442 catchErrorsZone.runWaitForCompletion(body); 453 return zone.runWaitForCompletion(body);
443 } 454 }
444 455 if (onDone == null) onDone = () {};
445 bool handleError(e) { 456 _Zone zone = new _CatchErrorsZone(_Zone._current, onError, onDone);
446 controller.add(e); 457 return zone.runWaitForCompletion(body);
447 return true;
448 }
449
450 void onDone() {
451 controller.close();
452 }
453
454 catchErrorsZone = new _CatchErrorsZone(_Zone._current, handleError, onDone);
455 controller = new StreamController(onListen: onListen);
456 return controller.stream;
457 } 458 }
458
459 Future waitForCompletion(void body()) {
460 Completer completer = new Completer.sync();
461 _Zone zone = new _WaitForCompletionZone(_Zone._current, completer.complete);
462 zone.runWaitForCompletion(body);
463 return completer.future;
464 }
OLDNEW
« no previous file with comments | « no previous file | tests/lib/async/catch_errors.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698