Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 /** Throws the given error in the next cycle. */ | |
| 8 _throwDelayed(var error, [Object stackTrace]) { | |
| 9 // We are going to reach the top-level here, but there might be a global | |
| 10 // exception handler. This means that we shouldn't print the stack trace. | |
| 11 // TODO(floitsch): Find better solution that doesn't print the stack trace | |
| 12 // if there is a global exception handler. | |
| 13 runAsync(() { | |
| 14 if (stackTrace != null) print(stackTrace); | |
| 15 var trace = getAttachedStackTrace(error); | |
| 16 if (trace != null && trace != stackTrace) print(trace); | |
| 17 throw error; | |
| 18 }); | |
| 19 } | |
| 20 | |
| 21 /** Abstract and private interface for a place to put events. */ | 7 /** Abstract and private interface for a place to put events. */ |
| 22 abstract class _EventSink<T> { | 8 abstract class _EventSink<T> { |
| 23 void _add(T data); | 9 void _add(T data); |
| 24 void _addError(Object error); | 10 void _addError(Object error); |
| 25 void _close(); | 11 void _close(); |
| 26 } | 12 } |
| 27 | 13 |
| 28 /** | 14 /** |
| 29 * Abstract and private interface for a place to send events. | 15 * Abstract and private interface for a place to send events. |
| 30 * | 16 * |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 89 static const int _STATE_HAS_PENDING = 32; | 75 static const int _STATE_HAS_PENDING = 32; |
| 90 static const int _STATE_PAUSE_COUNT = 64; | 76 static const int _STATE_PAUSE_COUNT = 64; |
| 91 static const int _STATE_PAUSE_COUNT_SHIFT = 6; | 77 static const int _STATE_PAUSE_COUNT_SHIFT = 6; |
| 92 | 78 |
| 93 /* Event handlers provided in constructor. */ | 79 /* Event handlers provided in constructor. */ |
| 94 /* TODO(7733): Fix Function->_DataHandler<T> when dart2js understands | 80 /* TODO(7733): Fix Function->_DataHandler<T> when dart2js understands |
| 95 * parameterized function types. */ | 81 * parameterized function types. */ |
| 96 Function _onData; | 82 Function _onData; |
| 97 _ErrorHandler _onError; | 83 _ErrorHandler _onError; |
| 98 _DoneHandler _onDone; | 84 _DoneHandler _onDone; |
| 85 final _Zone _zone = _Zone.current; | |
| 99 | 86 |
| 100 /** Bit vector based on state-constants above. */ | 87 /** Bit vector based on state-constants above. */ |
| 101 int _state; | 88 int _state; |
| 102 | 89 |
| 103 /** | 90 /** |
| 104 * Queue of pending events. | 91 * Queue of pending events. |
| 105 * | 92 * |
| 106 * Is created when necessary, or set in constructor for preconfigured events. | 93 * Is created when necessary, or set in constructor for preconfigured events. |
| 107 */ | 94 */ |
| 108 _PendingEvents _pending; | 95 _PendingEvents _pending; |
| 109 | 96 |
| 110 _BufferingStreamSubscription(this._onData, | 97 _BufferingStreamSubscription(this._onData, |
| 111 this._onError, | 98 this._onError, |
| 112 this._onDone, | 99 this._onDone, |
| 113 bool cancelOnError) | 100 bool cancelOnError) |
| 114 : _state = (cancelOnError ? _STATE_CANCEL_ON_ERROR : 0) { | 101 : _state = (cancelOnError ? _STATE_CANCEL_ON_ERROR : 0) { |
| 115 assert(_onData != null); | 102 assert(_onData != null); |
| 116 assert(_onError != null); | 103 assert(_onError != null); |
| 117 assert(_onDone != null); | 104 assert(_onDone != null); |
| 105 _zone.expectCallback(); | |
| 118 } | 106 } |
| 119 | 107 |
| 120 /** | 108 /** |
| 121 * Sets the subscription's pending events object. | 109 * Sets the subscription's pending events object. |
| 122 * | 110 * |
| 123 * This can only be done once. The pending events object is used for the | 111 * This can only be done once. The pending events object is used for the |
| 124 * rest of the subscription's life cycle. | 112 * rest of the subscription's life cycle. |
| 125 */ | 113 */ |
| 126 void _setPendingEvents(_PendingEvents pendingEvents) { | 114 void _setPendingEvents(_PendingEvents pendingEvents) { |
| 127 assert(_pending == null); | 115 assert(_pending == null); |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 226 bool get _isPaused => _state >= _STATE_PAUSE_COUNT; | 214 bool get _isPaused => _state >= _STATE_PAUSE_COUNT; |
| 227 bool get _canFire => _state < _STATE_IN_CALLBACK; | 215 bool get _canFire => _state < _STATE_IN_CALLBACK; |
| 228 bool get _mayResumeInput => | 216 bool get _mayResumeInput => |
| 229 !_isPaused && (_pending == null || _pending.isEmpty); | 217 !_isPaused && (_pending == null || _pending.isEmpty); |
| 230 bool get _cancelOnError => (_state & _STATE_CANCEL_ON_ERROR) != 0; | 218 bool get _cancelOnError => (_state & _STATE_CANCEL_ON_ERROR) != 0; |
| 231 | 219 |
| 232 bool get isPaused => _isPaused; | 220 bool get isPaused => _isPaused; |
| 233 | 221 |
| 234 void _cancel() { | 222 void _cancel() { |
| 235 _state |= _STATE_CANCELED; | 223 _state |= _STATE_CANCELED; |
| 224 _zone.unexpectCallback(); | |
|
Lasse Reichstein Nielsen
2013/05/29 08:32:26
Hmm, seeing it like this: unexpect is not a verb.
floitsch
2013/05/29 15:48:56
cancelCallbackExpectation
| |
| 236 if (_hasPending) { | 225 if (_hasPending) { |
| 237 _pending.cancelSchedule(); | 226 _pending.cancelSchedule(); |
| 238 } | 227 } |
| 239 } | 228 } |
| 240 | 229 |
| 241 /** | 230 /** |
| 242 * Increment the pause count. | 231 * Increment the pause count. |
| 243 * | 232 * |
| 244 * Also marks input as paused. | 233 * Also marks input as paused. |
| 245 */ | 234 */ |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 286 _state |= _STATE_CLOSED; | 275 _state |= _STATE_CLOSED; |
| 287 if (_canFire) { | 276 if (_canFire) { |
| 288 _sendDone(); | 277 _sendDone(); |
| 289 } else { | 278 } else { |
| 290 _addPending(const _DelayedDone()); | 279 _addPending(const _DelayedDone()); |
| 291 } | 280 } |
| 292 } | 281 } |
| 293 | 282 |
| 294 // Hooks called when the input is paused, unpaused or canceled. | 283 // Hooks called when the input is paused, unpaused or canceled. |
| 295 // These must not throw. If overwritten to call user code, include suitable | 284 // These must not throw. If overwritten to call user code, include suitable |
| 296 // try/catch wrapping and send any errors to [_throwDelayed]. | 285 // try/catch wrapping and send any errors to |
| 286 // [_Zone.current.handleUncaughtError]. | |
| 297 void _onPause() { | 287 void _onPause() { |
| 298 assert(_isInputPaused); | 288 assert(_isInputPaused); |
| 299 } | 289 } |
| 300 | 290 |
| 301 void _onResume() { | 291 void _onResume() { |
| 302 assert(!_isInputPaused); | 292 assert(!_isInputPaused); |
| 303 } | 293 } |
| 304 | 294 |
| 305 void _onCancel() { | 295 void _onCancel() { |
| 306 assert(_isCanceled); | 296 assert(_isCanceled); |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 327 } | 317 } |
| 328 | 318 |
| 329 /* _EventDispatch interface. */ | 319 /* _EventDispatch interface. */ |
| 330 | 320 |
| 331 void _sendData(T data) { | 321 void _sendData(T data) { |
| 332 assert(!_isCanceled); | 322 assert(!_isCanceled); |
| 333 assert(!_isPaused); | 323 assert(!_isPaused); |
| 334 assert(!_inCallback); | 324 assert(!_inCallback); |
| 335 bool wasInputPaused = _isInputPaused; | 325 bool wasInputPaused = _isInputPaused; |
| 336 _state |= _STATE_IN_CALLBACK; | 326 _state |= _STATE_IN_CALLBACK; |
| 337 try { | 327 _zone.executeGuardedPeriodicCallback(() => _onData(data)); |
| 338 _onData(data); | |
| 339 } catch (e, s) { | |
| 340 _throwDelayed(e, s); | |
| 341 } | |
| 342 _state &= ~_STATE_IN_CALLBACK; | 328 _state &= ~_STATE_IN_CALLBACK; |
| 343 _checkState(wasInputPaused); | 329 _checkState(wasInputPaused); |
| 344 } | 330 } |
| 345 | 331 |
| 346 void _sendError(var error) { | 332 void _sendError(var error) { |
| 347 assert(!_isCanceled); | 333 assert(!_isCanceled); |
| 348 assert(!_isPaused); | 334 assert(!_isPaused); |
| 349 assert(!_inCallback); | 335 assert(!_inCallback); |
| 336 if (!_zone.inSameErrorZone(_Zone.current)) { | |
| 337 // Errors are not allowed to traverse zone boundaries. | |
| 338 _Zone.current.handleUncaughtError(error); | |
| 339 return; | |
| 340 } | |
| 350 bool wasInputPaused = _isInputPaused; | 341 bool wasInputPaused = _isInputPaused; |
| 351 _state |= _STATE_IN_CALLBACK; | 342 _state |= _STATE_IN_CALLBACK; |
| 352 try { | 343 _zone.executeGuardedPeriodicCallback(() => _onError(error)); |
| 353 _onError(error); | |
| 354 } catch (e, s) { | |
| 355 _throwDelayed(e, s); | |
| 356 } | |
| 357 _state &= ~_STATE_IN_CALLBACK; | 344 _state &= ~_STATE_IN_CALLBACK; |
| 358 if (_cancelOnError) { | 345 if (_cancelOnError) { |
| 359 _cancel(); | 346 _cancel(); |
| 360 } | 347 } |
| 361 _checkState(wasInputPaused); | 348 _checkState(wasInputPaused); |
| 362 } | 349 } |
| 363 | 350 |
| 364 void _sendDone() { | 351 void _sendDone() { |
| 365 assert(!_isCanceled); | 352 assert(!_isCanceled); |
| 366 assert(!_isPaused); | 353 assert(!_isPaused); |
| 367 assert(!_inCallback); | 354 assert(!_inCallback); |
| 368 _state |= (_STATE_CANCELED | _STATE_CLOSED | _STATE_IN_CALLBACK); | 355 _state |= (_STATE_CANCELED | _STATE_CLOSED | _STATE_IN_CALLBACK); |
| 369 try { | 356 _zone.executeGuardedCallback(_onDone); |
| 370 _onDone(); | |
| 371 } catch (e, s) { | |
| 372 _throwDelayed(e, s); | |
| 373 } | |
| 374 _onCancel(); // No checkState after cancel, it is always the last event. | 357 _onCancel(); // No checkState after cancel, it is always the last event. |
| 375 _state &= ~_STATE_IN_CALLBACK; | 358 _state &= ~_STATE_IN_CALLBACK; |
| 376 } | 359 } |
| 377 | 360 |
| 378 /** | 361 /** |
| 379 * Call a hook function. | 362 * Call a hook function. |
| 380 * | 363 * |
| 381 * The call is properly wrapped in code to avoid other callbacks | 364 * The call is properly wrapped in code to avoid other callbacks |
| 382 * during the call, and it checks for state changes after the call | 365 * during the call, and it checks for state changes after the call |
| 383 * that should cause further callbacks. | 366 * that should cause further callbacks. |
| (...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 544 typedef void _DataHandler<T>(T value); | 527 typedef void _DataHandler<T>(T value); |
| 545 typedef void _ErrorHandler(error); | 528 typedef void _ErrorHandler(error); |
| 546 typedef void _DoneHandler(); | 529 typedef void _DoneHandler(); |
| 547 | 530 |
| 548 | 531 |
| 549 /** Default data handler, does nothing. */ | 532 /** Default data handler, does nothing. */ |
| 550 void _nullDataHandler(var value) {} | 533 void _nullDataHandler(var value) {} |
| 551 | 534 |
| 552 /** Default error handler, reports the error to the global handler. */ | 535 /** Default error handler, reports the error to the global handler. */ |
| 553 void _nullErrorHandler(error) { | 536 void _nullErrorHandler(error) { |
| 554 _throwDelayed(error); | 537 _Zone.current.handleUncaughtError(error); |
| 555 } | 538 } |
| 556 | 539 |
| 557 /** Default done handler, does nothing. */ | 540 /** Default done handler, does nothing. */ |
| 558 void _nullDoneHandler() {} | 541 void _nullDoneHandler() {} |
| 559 | 542 |
| 560 | 543 |
| 561 /** A delayed event on a buffering stream subscription. */ | 544 /** A delayed event on a buffering stream subscription. */ |
| 562 abstract class _DelayedEvent { | 545 abstract class _DelayedEvent { |
| 563 /** Added as a linked list on the [StreamController]. */ | 546 /** Added as a linked list on the [StreamController]. */ |
| 564 _DelayedEvent next; | 547 _DelayedEvent next; |
| (...skipping 648 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1213 _FutureImpl<bool> hasNext = _futureOrPrefetch; | 1196 _FutureImpl<bool> hasNext = _futureOrPrefetch; |
| 1214 _clear(); | 1197 _clear(); |
| 1215 hasNext._setValue(false); | 1198 hasNext._setValue(false); |
| 1216 return; | 1199 return; |
| 1217 } | 1200 } |
| 1218 _subscription.pause(); | 1201 _subscription.pause(); |
| 1219 _futureOrPrefetch = null; | 1202 _futureOrPrefetch = null; |
| 1220 _state = _STATE_EXTRA_DONE; | 1203 _state = _STATE_EXTRA_DONE; |
| 1221 } | 1204 } |
| 1222 } | 1205 } |
| OLD | NEW |