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 deprecatedFutureValue(_FutureImpl future) => | 7 deprecatedFutureValue(_FutureImpl future) => |
| 8 future._isComplete ? future._resultOrListeners : null; | 8 future._isComplete ? future._resultOrListeners : null; |
| 9 | 9 |
| 10 abstract class _Completer<T> implements Completer<T> { | 10 abstract class _Completer<T> implements Completer<T> { |
| (...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 174 /// forwarded directly to the other future. | 174 /// forwarded directly to the other future. |
| 175 static const int _CHAINED = 2; | 175 static const int _CHAINED = 2; |
| 176 /// The future has been chained to another future, but there hasn't been | 176 /// The future has been chained to another future, but there hasn't been |
| 177 /// any listeners added to this future yet. If it is completed with an | 177 /// any listeners added to this future yet. If it is completed with an |
| 178 /// error, the error will be considered unhandled. | 178 /// error, the error will be considered unhandled. |
| 179 static const int _CHAINED_UNLISTENED = 6; | 179 static const int _CHAINED_UNLISTENED = 6; |
| 180 /// The future has been completed with a value result. | 180 /// The future has been completed with a value result. |
| 181 static const int _VALUE = 8; | 181 static const int _VALUE = 8; |
| 182 /// The future has been completed with an error result. | 182 /// The future has been completed with an error result. |
| 183 static const int _ERROR = 12; | 183 static const int _ERROR = 12; |
| 184 /// Extra bit set when the future has been completed with an error result. | |
| 185 /// but no listener has been scheduled to receive the error. | |
| 186 /// If the bit is still set when a [runAsync] call triggers, the error will | |
| 187 /// be reported to the top-level handler. | |
| 188 /// Assigning a listener before that time will clear the bit. | |
| 189 static const int _UNHANDLED_ERROR = 16; | |
| 190 | 184 |
| 191 /** Whether the future is complete, and as what. */ | 185 /** Whether the future is complete, and as what. */ |
| 192 int _state = _INCOMPLETE; | 186 int _state = _INCOMPLETE; |
| 193 | 187 |
| 194 final _Zone _zone = _Zone.current.fork(); | 188 final _Zone _zone = _Zone.current.fork(); |
| 195 | 189 |
| 196 bool get _isChained => (_state & _CHAINED) != 0; | 190 bool get _isChained => (_state & _CHAINED) != 0; |
| 197 bool get _hasChainedListener => _state == _CHAINED; | 191 bool get _hasChainedListener => _state == _CHAINED; |
| 198 bool get _isComplete => _state >= _VALUE; | 192 bool get _isComplete => _state >= _VALUE; |
| 199 bool get _mayComplete => _state == _INCOMPLETE; | 193 bool get _mayComplete => _state == _INCOMPLETE; |
| 200 bool get _hasValue => _state == _VALUE; | 194 bool get _hasValue => _state == _VALUE; |
| 201 bool get _hasError => _state >= _ERROR; | 195 bool get _hasError => _state >= _ERROR; |
| 202 bool get _hasUnhandledError => _state >= _UNHANDLED_ERROR; | |
| 203 | |
| 204 void _clearUnhandledError() { | |
| 205 _state &= ~_UNHANDLED_ERROR; | |
| 206 } | |
| 207 | 196 |
| 208 /** | 197 /** |
| 209 * Either the result, a list of listeners or another future. | 198 * Either the result, a list of listeners or another future. |
| 210 * | 199 * |
| 211 * The result of the future is either a value or an error. | 200 * The result of the future is either a value or an error. |
| 212 * A result is only stored when the future has completed. | 201 * A result is only stored when the future has completed. |
| 213 * | 202 * |
| 214 * The listeners is an internally linked list of [_FutureListener]s. | 203 * The listeners is an internally linked list of [_FutureListener]s. |
| 215 * Listeners are only remembered while the future is not yet complete, | 204 * Listeners are only remembered while the future is not yet complete, |
| 216 * and it is not chained to another future. | 205 * and it is not chained to another future. |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 231 _FutureImpl.immediate(T value) { | 220 _FutureImpl.immediate(T value) { |
| 232 _state = _VALUE; | 221 _state = _VALUE; |
| 233 _resultOrListeners = value; | 222 _resultOrListeners = value; |
| 234 } | 223 } |
| 235 | 224 |
| 236 _FutureImpl.immediateError(var error, [Object stackTrace]) { | 225 _FutureImpl.immediateError(var error, [Object stackTrace]) { |
| 237 if (stackTrace != null) { | 226 if (stackTrace != null) { |
| 238 // Force stack trace onto error, even if it had already one. | 227 // Force stack trace onto error, even if it had already one. |
| 239 _attachStackTrace(error, stackTrace); | 228 _attachStackTrace(error, stackTrace); |
| 240 } | 229 } |
| 241 _setError(error); | 230 _asyncSetError(error); |
| 242 } | 231 } |
| 243 | 232 |
| 244 factory _FutureImpl.wait(Iterable<Future> futures) { | 233 factory _FutureImpl.wait(Iterable<Future> futures) { |
| 245 Completer completer; | 234 Completer completer; |
| 246 // List collecting values from the futures. | 235 // List collecting values from the futures. |
| 247 // Set to null if an error occurs. | 236 // Set to null if an error occurs. |
| 248 List values; | 237 List values; |
| 249 void handleError(error) { | 238 void handleError(error) { |
| 250 if (values != null) { | 239 if (values != null) { |
| 251 values = null; | 240 values = null; |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 325 hasListeners = (_state == _CHAINED); // and not _CHAINED_UNLISTENED. | 314 hasListeners = (_state == _CHAINED); // and not _CHAINED_UNLISTENED. |
| 326 } else { | 315 } else { |
| 327 listeners = _removeListeners(); | 316 listeners = _removeListeners(); |
| 328 hasListeners = (listeners != null); | 317 hasListeners = (listeners != null); |
| 329 } | 318 } |
| 330 | 319 |
| 331 _state = _ERROR; | 320 _state = _ERROR; |
| 332 _resultOrListeners = error; | 321 _resultOrListeners = error; |
| 333 | 322 |
| 334 if (!hasListeners) { | 323 if (!hasListeners) { |
| 335 _scheduleUnhandledError(); | 324 // TODO(floitsch): Hook this into unhandled error handling. |
| 325 var error = _resultOrListeners; | |
|
Lasse Reichstein Nielsen
2013/09/05 09:17:25
Why the alias for error here? Just remove the "var
| |
| 326 _zone.handleUncaughtError(error); | |
| 336 return; | 327 return; |
| 337 } | 328 } |
| 338 while (listeners != null) { | 329 while (listeners != null) { |
| 339 _FutureListener listener = listeners; | 330 _FutureListener listener = listeners; |
| 340 listeners = listener._nextListener; | 331 listeners = listener._nextListener; |
| 341 listener._nextListener = null; | 332 listener._nextListener = null; |
| 342 listener._sendError(error); | 333 listener._sendError(error); |
| 343 } | 334 } |
| 344 } | 335 } |
| 345 | 336 |
| 346 void _asyncSetValue(T value) { | 337 void _asyncSetValue(T value) { |
| 347 if (!_mayComplete) throw new StateError("Future already completed"); | 338 if (!_mayComplete) throw new StateError("Future already completed"); |
| 348 _state = _PENDING_COMPLETE; | 339 _state = _PENDING_COMPLETE; |
| 349 runAsync(() { _setValueUnchecked(value); }); | 340 runAsync(() { _setValueUnchecked(value); }); |
| 350 } | 341 } |
| 351 | 342 |
| 352 void _asyncSetError(Object error) { | 343 void _asyncSetError(Object error) { |
| 353 if (!_mayComplete) throw new StateError("Future already completed"); | 344 if (!_mayComplete) throw new StateError("Future already completed"); |
| 354 _state = _PENDING_COMPLETE; | 345 _state = _PENDING_COMPLETE; |
| 355 runAsync(() { _setErrorUnchecked(error); }); | 346 runAsync(() { _setErrorUnchecked(error); }); |
| 356 } | 347 } |
| 357 | 348 |
| 358 void _scheduleUnhandledError() { | |
| 359 assert(_state == _ERROR); | |
| 360 _state = _ERROR | _UNHANDLED_ERROR; | |
| 361 // Wait for the rest of the current event's duration to see | |
| 362 // if a subscriber is added to handle the error. | |
| 363 runAsync(() { | |
| 364 if (_hasUnhandledError) { | |
| 365 // No error handler has been added since the error was set. | |
| 366 _clearUnhandledError(); | |
| 367 // TODO(floitsch): Hook this into unhandled error handling. | |
| 368 var error = _resultOrListeners; | |
| 369 _zone.handleUncaughtError(error); | |
| 370 } | |
| 371 }); | |
| 372 } | |
| 373 | |
| 374 void _addListener(_FutureListener listener) { | 349 void _addListener(_FutureListener listener) { |
| 375 assert(listener._nextListener == null); | 350 assert(listener._nextListener == null); |
| 376 if (!listener._inSameErrorZone(_zone)) { | 351 if (!listener._inSameErrorZone(_zone)) { |
| 377 listener = new _ErrorZoneBoundaryListener(listener); | 352 listener = new _ErrorZoneBoundaryListener(listener); |
| 378 } | 353 } |
| 379 if (_isChained) { | 354 if (_isChained) { |
| 380 _state = _CHAINED; // In case it was _CHAINED_UNLISTENED. | 355 _state = _CHAINED; // In case it was _CHAINED_UNLISTENED. |
| 381 _FutureImpl resultSource = _chainSource; | 356 _FutureImpl resultSource = _chainSource; |
| 382 resultSource._addListener(listener); | 357 resultSource._addListener(listener); |
| 383 return; | 358 return; |
| 384 } | 359 } |
| 385 if (_isComplete) { | 360 if (_isComplete) { |
| 386 _clearUnhandledError(); | |
| 387 // Handle late listeners asynchronously. | 361 // Handle late listeners asynchronously. |
| 388 runAsync(() { | 362 runAsync(() { |
| 389 if (_hasValue) { | 363 if (_hasValue) { |
| 390 T value = _resultOrListeners; | 364 T value = _resultOrListeners; |
| 391 listener._sendValue(value); | 365 listener._sendValue(value); |
| 392 } else { | 366 } else { |
| 393 assert(_hasError); | 367 assert(_hasError); |
| 394 listener._sendError(_resultOrListeners); | 368 listener._sendError(_resultOrListeners); |
| 395 } | 369 } |
| 396 }); | 370 }); |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 424 * immediately. This function is only called during event resolution | 398 * immediately. This function is only called during event resolution |
| 425 * where it's acceptable to send an event. | 399 * where it's acceptable to send an event. |
| 426 */ | 400 */ |
| 427 void _chain(_FutureImpl future) { | 401 void _chain(_FutureImpl future) { |
| 428 if (!_isComplete) { | 402 if (!_isComplete) { |
| 429 future._chainFromFuture(this); | 403 future._chainFromFuture(this); |
| 430 } else if (_hasValue) { | 404 } else if (_hasValue) { |
| 431 future._setValue(_resultOrListeners); | 405 future._setValue(_resultOrListeners); |
| 432 } else { | 406 } else { |
| 433 assert(_hasError); | 407 assert(_hasError); |
| 434 _clearUnhandledError(); | |
| 435 future._setError(_resultOrListeners); | 408 future._setError(_resultOrListeners); |
| 436 } | 409 } |
| 437 } | 410 } |
| 438 | 411 |
| 439 /** | 412 /** |
| 440 * Returns the future that this future is chained to. | 413 * Returns the future that this future is chained to. |
| 441 * | 414 * |
| 442 * If that future is itself chained to something else, | 415 * If that future is itself chained to something else, |
| 443 * get the [_chainSource] of that future instead, and make this | 416 * get the [_chainSource] of that future instead, and make this |
| 444 * future chain directly to the earliest source. | 417 * future chain directly to the earliest source. |
| (...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 678 _setError(error); | 651 _setError(error); |
| 679 }, onError: _setError); | 652 }, onError: _setError); |
| 680 return; | 653 return; |
| 681 } | 654 } |
| 682 } catch (e, s) { | 655 } catch (e, s) { |
| 683 error = _asyncError(e, s); | 656 error = _asyncError(e, s); |
| 684 } | 657 } |
| 685 _setError(error); | 658 _setError(error); |
| 686 } | 659 } |
| 687 } | 660 } |
| OLD | NEW |