Chromium Code Reviews| 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 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 } | |
| OLD | NEW |